Understanding Prototype and this
This question already has an answer here:
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
下一篇: 了解原型和这个