Scope chain look-up vs prototype look-up - Which is when

后端 未结 1 518
梦谈多话
梦谈多话 2021-02-01 08:22

If a variable is not available in a function when it\'s needed, then it\'s being looked for in the scope chain (which is a closure), but other times it\'s being searched for in

相关标签:
1条回答
  • 2021-02-01 08:32

    Variables are looked up on the scope chain, starting with the current execution context and going up the tree of enclosing execution contexts.

    Properties are looked up firstly on the base object, then on that object's [[Prototoype]] chain (i.e. its internal prototype).

    So if you do:

    foo
    

    foo will be treated as a variable and looked up on the scope chain. Variable names are never qualified, you can't direct them to a specific execution context to be looked up in. If there are two variables on the scope chain with the same name, you can only access the one that is first encountered when going along the chain (there is a way around this specifically for global variables), e.g.

    var a = 'global a';
    
    function foo() {
      var a = 'local a';
      return a;
    }
    
    console.log(foo()); // local a
    

    In the above, a within the function resolves to the local variable a. In the case of global variables, they are made properties of the global object so you can access them even if they are "shadowed" by a same named local property, e.g.

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

    In contrast, property names are always preceded by a base object on which they are looked up (as in the example above, where this references the global object), e.g.

    foo.bar
    

    will be split into foo and bar. Firstly, foo will be resolved on the scope chain and, if found, property resolution will try to find a bar property. So for properties, you can direct which object the property is looked up on. So if there are two objects with a same named property, you can look up both properties as long as both objects are in scope.

    So the first part of any reference is treated as a variable, the subsequent parts are treated as properties. Except when with is used, but that is discouraged. Don't go there.

    But for completeness… with places the specified object on the start scope chain so that variables are first looked up as properties of that object before using the scope chain, so you can do:

    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();
    
    0 讨论(0)
提交回复
热议问题