我正在学习javascript,但我对函数/闭包有一些疑问,我有这个代码:
var obj = { value: 0 };
obj.test = function() {
var that = this;
var f1 = function() {
console.log(that);
};
f1();
};
obj.test();
var x = obj.test;
x();
我知道当调用函数时,如f()this
引用全局对象,但在我的示例中,当定义f1时,它对that
的{{1}}有一个引用this
引用obj的外部函数。
我希望函数能记住创建它的上下文,那么为什么最后一次调用x()
引用了全局对象?
由于
答案 0 :(得分:3)
我希望函数能够记住创建它的上下文
这就是你的错误。 JavaScript函数不"记住"在这种情况下与任何特定对象的任何关系。他们唯一记得的是父词汇上下文链中的范围内变量。在这种情况下," obj"变量就是这样一个变量。
您可以显式创建一个使用.bind()
方法记住与对象的关系的函数。
obj.boundTest = obj.test.bind(obj);
var x = obj.boundTest;
x(); // will do the right thing
甚至更简单:
var x = obj.test.bind(obj);
x();
答案 1 :(得分:2)
我希望函数能够记住创建它的上下文
它没有。
上下文取决于函数的调用方式,仅取决于函数的调用方式。
您在全局上下文中调用它,因此this
是全局对象。
答案 2 :(得分:1)
发生这种情况的原因是当您复制该功能时
var x = obj.test;
您仅复制该功能。不是对象,也不是任何变量。因此,当您尝试运行x(即obj.test)时,它会运行新鲜。结果是this
被重新评估,现在引用全局上下文(或在严格模式下未定义)。