最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Scope chain look-up vs prototype look-up - Which is when - Stack Overflow

programmeradmin2浏览0评论

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 the prototype chain. I am trying to wrap my head around which is happening when. I was wondering if someone could kindly clear the mist for me, or refer me to some literature discussing this topic specifically.

For example, would I be right saying that: - Objects and therefore public variables tied to the context (this)are always looked up in the prototype chain? - Private variables are always looked up in the scope chain (i.e. chain of functions in the execution context)? - Are there any cases when the program is looking in both/either?

I tested three different scenarios(scope chain look-up, prototype look-up and no look-up), but unfortunately It haven't helped enough to get to the bottom of 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
    })();

Thanks!

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 the prototype chain. I am trying to wrap my head around which is happening when. I was wondering if someone could kindly clear the mist for me, or refer me to some literature discussing this topic specifically.

For example, would I be right saying that: - Objects and therefore public variables tied to the context (this)are always looked up in the prototype chain? - Private variables are always looked up in the scope chain (i.e. chain of functions in the execution context)? - Are there any cases when the program is looking in both/either?

I tested three different scenarios(scope chain look-up, prototype look-up and no look-up), but unfortunately It haven't helped enough to get to the bottom of 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
    })();

Thanks!

Share Improve this question asked Dec 11, 2014 at 23:28 CrocodileCrocodile 5,84511 gold badges46 silver badges75 bronze badges 5
  • 2 The prototype chain will only be looked up when you access a property value on an object using a dot operator or square brackets (the object may either be referenced by a variable or by the current context this). If you reference a variable by its identifier, it will be looked up starting with the current function's scope, and then working up to higher level closures. This is why when you define an argument called t for a function, it shadows any closed-over variable called t. Same thing if you declare a var t within a function. Not exactly sure if this answers all your questions. – sbking Commented Dec 11, 2014 at 23:36
  • 2 So in other words, prototype lookup and variable lookup are entirely separate in JavaScript. If you reference a value directly by a variable rather than as a property on an object, JavaScript doesn't have any object on whose prototype chain to do a lookup. – sbking Commented Dec 11, 2014 at 23:43
  • Thanks this is exactly what I am getting at! i) Is it always EITHER scope chain look-up or prototype chain look-up, but not both? ii.)If "you access a property value on an object using a dot operator or square brackets", does it means that it will always be looked up in the prototype chain and not the scope chain? - If "you reference a variable by its identifier" does it mean that it is always looked up in the scope chain? – Crocodile Commented Dec 11, 2014 at 23:44
  • Yes, you've got the idea. Also remember that a function's context is dynamic (it can be set at call-time by using a dot operator/square brackets or with the call, apply, or bind function methods), while a function's reference environment is not (it is determined when you define the function). – sbking Commented Dec 11, 2014 at 23:52
  • davidshariff.com/blog/javascript-scope-chain-and-closures – Ian Warburton Commented Sep 8, 2015 at 23:00
Add a comment  | 

1 Answer 1

Reset to default 24

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)

  1. 暂无评论