【发布时间】:2016-02-15 05:59:05
【问题描述】:
在此示例中,为什么将函数引用推入数组不会改变 scopeexecution context 的 this 而将函数引用分配给新变量确实会改变 scopeexecution context of this?
(function() {
function Car(year) {
this.year = year;
}
Car.prototype = {
logYear: function() {
console.log(this.year);
}
};
var ford = new Car('Ford', 1999);
ford.logYear();
var cbs = [];
cbs.push(ford.logYear);
for(var x = 0; x < cbs.length; x++) {
cbs[x](); // -> 1999 #1
var callback = cbs[x];
callback(); // -> undefined #2
}
})()
这是因为对数组中函数的引用指向ford 对象上的原始函数,其中this 仍被定义为实例(#1)并且变量赋值将this 更改为指向到包装 IIFE 块(#2)?
如果我需要从各种对象中收集一堆这样的方法并在其他地方调用它们,这是一个很好的模式吗?
这种引用调用与console.error.bind(console) 等示例有何关联?
谢谢!
-- 更新
感谢@Satyajeet 的精彩解释和澄清。
除了我最初提出这个问题的原因之外,拼写错误和复制错误是我怀疑 Satyajeet 确认的内容,但我正在处理的应用程序并未反映这种行为(或者我认为如此)。
事实证明,在应用程序中,我正在执行与上面调用cbs.push(ford.logYear); 的代码类似的过程,将来自不同对象的多个方法添加到数组中。
在应用程序中的某个时刻,我调用了所有这些方法,并期望它们的行为方式与在原始对象的 execution contextscope 中调用它们时的行为方式相同...确实如此,因为与方法交互的值未附加到 this,它们被捕获在闭包中。
查看示例 plunker here
-- 更新 2
修正了execution context 和scope 的用法,以确保问题/答案的每个部分都准确无误。
【问题讨论】:
-
` cbs[x](); // -> 1999 #1`不会打印任何
Ford或1999,它正在打印undefined -
JS 被阻塞作用域。所以
this只会在函数中调用时改变。您的cbs数组与Car处于同一范围内 -
实际上,您的第一个控制台日志来自您执行
ford.logYear();,您在所有其他日志消息中都未定义。所以你正在改变this的范围,你只是误解了日志消息 -
@PatrickEvans 啊,谢谢!这就是我迟到编码和复制粘贴所得到的。
标签: javascript function this