Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 范围链查找与原型查找-何时_Javascript_Closures_Prototypal Inheritance_Scope Chain - Fatal编程技术网

Javascript 范围链查找与原型查找-何时

Javascript 范围链查找与原型查找-何时,javascript,closures,prototypal-inheritance,scope-chain,Javascript,Closures,Prototypal Inheritance,Scope Chain,如果一个变量在需要时在函数中不可用,那么它会在范围链中被查找(这是一个闭包),但其他时候它会在原型链中被搜索。我试着把我的脑袋绕在发生什么事情的时候。我想知道是否有人能帮我澄清一下,或者让我参考一些专门讨论这个话题的文献 例如,我说的对吗: -对象,因此绑定到上下文(this)的公共变量总是在原型链中查找? -始终在范围链(即执行上下文中的函数链)中查找私有变量-是否存在程序同时查看两个/其中一个的情况 我测试了三种不同的场景(范围链查找、原型查找和不查找),但不幸的是,它没有提供足够的帮助,无

如果一个变量在需要时在函数中不可用,那么它会在范围链中被查找(这是一个闭包),但其他时候它会在原型链中被搜索。我试着把我的脑袋绕在发生什么事情的时候。我想知道是否有人能帮我澄清一下,或者让我参考一些专门讨论这个话题的文献

例如,我说的对吗: -对象,因此绑定到上下文(this)的公共变量总是在原型链中查找? -始终在范围链(即执行上下文中的函数链)中查找私有变量-是否存在程序同时查看两个/其中一个的情况

我测试了三种不同的场景(范围链查找、原型查找和不查找),但不幸的是,它没有提供足够的帮助,无法深入了解这一点

    var Food = function(){
    var t = 1;  // for closure

    this.timeToPrepare = function(){    // Scope chain lookup
        console.log(t * 3);
    };

    this.timeToMake = function(){   // This is looked up in the prototype chain
        console.log(this.t * 3);
    };

    this.timeToEat = function(t){   //No lookup
        console.log(t * 3);
    };

    };

    Food.prototype.t = 2;

    (function(){
    var pizza = new Food;
    pizza.timeToPrepare();  //3
    pizza.timeToMake();     //6
    pizza.timeToEat(3);     //9
    })();

谢谢

变量在作用域链上查找,从当前执行上下文开始,向上到封闭执行上下文树

属性首先在基本对象上查找,然后在该对象的
[[prototype]]
链(即其内部原型)上查找

因此,如果你这样做:

foo
foo将被视为变量,并在范围链上查找。变量名永远不会限定,您不能将它们指向要在其中查找的特定执行上下文。如果作用域链上有两个同名变量,则只能访问沿该链运行时首次遇到的变量(有一种方法专门针对全局变量),例如

在上面的例子中,函数中的a解析为局部变量a。对于全局变量,它们是全局对象的属性,因此您可以访问它们,即使它们被相同的命名局部属性“隐藏”,例如

function foo() {
  var = 'local a';
  // this will reference the global object
  return this.a;
}

console.log(foo()); // global a
与此相反,属性名称前总是有一个基础对象,在该对象上查找属性名称(如上面的示例中,它引用了全局对象),例如

将被分为foo和bar。首先,将在范围链上解析foo,如果找到,属性解析将尝试查找bar属性。因此,对于属性,可以指示查找属性的对象。因此,如果有两个对象具有相同的命名属性,只要两个对象都在范围内,就可以查找这两个属性

因此,任何引用的第一部分被视为变量,后续部分被视为属性。除非使用with,但不鼓励这样做。不要去那里

但是为了完整性…with将指定的对象放置在开始作用域链上,以便在使用作用域链之前首先将变量作为该对象的属性进行查找,因此您可以执行以下操作:

var cos = function(arg){return 'my cos function: ' + arg};

function foo() {

  // cos is resolved on the scope chain
  console.log(cos(0.5));  // my cos function: 0.5

  with (Math) {
    // cos is first resolved as a property of Math, and only on the
    // scope chain if not found there
    console.log(cos(0.5)) // 0.8775825618903728
  }
}

foo();

只有使用点运算符或方括号访问对象的属性值时,才会查找原型链(该对象可以由变量引用,也可以由当前上下文
this
引用)。如果通过标识符引用变量,则将从当前函数的作用域开始查找变量,然后查找更高级别的闭包。这就是为什么在为函数定义名为
t
的参数时,它会将名为
t
的封闭变量隐藏起来。如果在函数中声明一个
var t
,也是一样的。也就是说,原型查找和变量查找在JavaScript中是完全独立的。如果您直接通过变量引用值,而不是作为对象的属性引用值,则JavaScript没有任何对象的原型链可以进行查找。谢谢,这正是我的意思!i) 它总是范围链查找还是原型链查找,但不是两者都有?ii.)如果“使用点运算符或方括号访问对象上的属性值”,是否意味着将始终在原型链而不是范围链中查找该属性值?-如果“您通过标识符引用变量”,这是否意味着它总是在范围链中查找?是的,您已经知道了。还请记住,函数的上下文是动态的(可以在调用时使用点运算符/方括号或使用
调用
应用
、或
绑定
函数方法来设置),而函数的参考环境则不是动态的(在定义函数时确定)。
foo.bar
var cos = function(arg){return 'my cos function: ' + arg};

function foo() {

  // cos is resolved on the scope chain
  console.log(cos(0.5));  // my cos function: 0.5

  with (Math) {
    // cos is first resolved as a property of Math, and only on the
    // scope chain if not found there
    console.log(cos(0.5)) // 0.8775825618903728
  }
}

foo();