Understanding Prototype and this

This question already has an answer here:

  • How does JavaScript .prototype work? 21 answers

  • In JavaScript it's all about whether you instantiate or merely invoke a function. It's a constructor only in cases of the former. The difference, as you probably know already, is whether the new keyword is used before the function reference.

    It's this that controls what those properties inside your constructor are properties of .

    So in your case, they are not properties of the constructor (this is an unhelpful way of thinking of them); rather, they are properties of your instance .

    Invoked functions are executed in the window scope, and so if you merely invoke your function, this.foo etc would be setting properties on window .

    If you instantiate the function, however, they become properties on the instance, since an instance is implicitly returned from a function (constructor) that is instantiated rather than invoked. So:

    Invocation: properties are set on default context, window :

    function static_func() { this.foo = 'bar'; }
    static_func();
    window.foo; //'bar'
    

    Instantiation: properties are set on returned instance

    function constructor(val) { this.foo = val; }
    var instance = new constructor('bar');
    window.foo; //undefined
    instance.foo; //'bar'
    

    So you are confused why when you save this in a variable, it isn't "this" later on? There are several reasons why self isn't "this" later on in the keyup event.

    When a keyup event is called as a result of <input id="anyInputElement" /> , the keyup event's callback function's this is going to be that input. This is because a new execution context has been created resulting in this being assigned to the element.

    So why then isn't self , which you assigned to this , not the input element?

    Execution contexts are stack based. So when the parent function foo is instantiated with new it creates its own execution context. This is the parent context to the execution context used in the keyup callback because it comes lower in the stack. Each execution context also contains a lexical and variable environment. These environments contain the variables available (naming collision results in variable overwriting lexical).

    function foo(id)
    {
     var self = this;  //parent context
     this.element.addEventListener("keyup", function(){
      self.bar();  //child context
     }, false);
    }
    

    A lexical environment contains variables from the parent environment all the way up the stack (this is why window is accessible from everywhere for example). So the child execution context here (inside of the keyup callback) contains self in its lexical environment.

    self contains a copy of this from the parent execution context.

    As a result of that, when self is used that is the execution context (including lexical and variable environments) that is accessed. This is where the properties from foo come from. Note that because the keyup callback created its own execution context, it also has a newly created this (which means that self != this inside of the keyup event listener).

    Related: Save access to this scope

    链接地址: http://www.djcxy.com/p/30092.html

    上一篇: 这与原型Javascript

    下一篇: 了解原型和这个