理解原型和这个
Understanding Prototype and this
据我所知,"this"应该包含实际触发"this"函数的对象的属性和函数。但是在下面的例子中,它也包含构造函数"foo"的属性,为什么呢?
function foo(id)
{
var self = this;
this.foo = "foo";
this.element = document.getElementById(id);
this.element.addEventListener("keyup", function(){self.bar();}, false);
}
foo.prototype.bar = function()
{
console.log(this.element.value);
};
new foo("anyInputElement");
在JavaScript中,这是关于你是实例化还是仅仅调用一个函数。只有在前者的情况下,它才是构造函数。您可能已经知道,区别在于new
关键字是否在函数引用之前使用。
它控制构造函数中的属性是的属性
所以在你的例子中,它们不是构造函数的属性(这是一种无益的思考它们的方式);相反,它们是实例的属性。 被调用的函数在 如果你实例化了函数,但是,它们成为实例上的属性,因为实例是隐式地从实例化而不是调用的函数(构造函数)返回的。所以: 调用:属性在默认上下文中设置, Instantiation:属性被设置在返回的实例window
作用域中执行,因此,如果您仅仅调用您的函数,this.foo
等将在window
上设置属性。window
:function static_func() { this.foo = 'bar'; }
static_func();
window.foo; //'bar'
function constructor(val) { this.foo = val; }
var instance = new constructor('bar');
window.foo; //undefined
instance.foo; //'bar'
所以你很困惑为什么当你把它保存在一个变量中,它不是"this"以后?在keyup事件后面,self不是"this"有几个原因。
当keyup事件作为<input id="anyInputElement" />
的结果被调用时,keyup事件的回调函数的this
将是该输入。这是因为创建了一个新的执行上下文,导致this
被分配给元素。
那么为什么分配给this
的self
不是输入元素呢?
执行上下文基于堆栈。因此,当父函数foo用new实例化时,它创建了自己的执行上下文。这是keyup回调中使用的执行上下文的父上下文,因为它在堆栈中较低。每个执行上下文还包含一个词法和变量环境。这些环境包含可用的变量(命名冲突会导致变量覆盖词法)。
function foo(id)
{
var self = this; //parent context
this.element.addEventListener("keyup", function(){
self.bar(); //child context
}, false);
}
一个词法环境包含了从父环境一直到堆栈的变量(这就是为什么window
可以从任何地方访问)。因此这里的子执行上下文(在keyup回调中)在其词法环境中包含self
。
self
包含从父执行上下文中复制this
的。
因此,当使用self
时,访问的是执行上下文(包括词法和变量环境)。这就是foo
属性的来源。注意,因为keyup回调创建了自己的执行上下文,所以它也有一个新创建的this
(这意味着在keyup事件侦听器中self != this)。
相关:保存对这个作用域的访问
- 使用“;这个“;JavaScript原型方法中的关键字
- 引用类变量中的原型方法
- 如何从对象的原型方法访问JavaScript对象属性
- 为什么要包装每一个原型“;类“;JS中具有匿名函数的对象
- Node.js中的JavaScript原型对象效率
- 重载JS'firefox中的对象原型
- “util.inherits”和在NodeJS中扩展原型之间的区别
- 附加到原型属性的Do函数没有闭包
- 使用方括号访问插件原型函数
- 为什么JSON.stringify没有序列化原型值
- 为什么要返回'这'在导致循环的JavaScript原型中
- 带有对象/原型的链式承诺(Q延期)
- 如何覆盖原型中的事件侦听器
- 如何在Mocha/Chai中测试JS原型(非模块)
- 我将如何将Base的原型分配给User
- 原型和用法 Javascript
- 别名或以其他方式合并两个具有不同名称的相同对象原型
- JavaScript对象不是从原型链继承的
- 得到"未定义不是函数“;使用显示原型图案时出错
- 需要原型内部或外部的功能