我基本上有一个对象,通过其原型扩展了一个函数。在该函数内部,存在另一个函数,但是当在此嵌套函数中使用this
时,它似乎不是引用该对象,而是函数。
例如,
var sampleObject = function() {
this.foo = 123;
}
sampleObject.prototype.getFoo = function() {
var nested = function() {
return this.foo;
}
return nested();
}
var test = new sampleObject();
window.alert(test.getFoo()); // undefined
this.foo
未引用123值,但未定义,因为它指的是嵌套函数,其中不存在foo
。如何从嵌套函数中访问123值?
答案 0 :(得分:35)
sampleObject.prototype.getFoo = function() {
var me = this;
var nested = function() {
return me.foo;
}
return nested;
}
通过将this
的值保存在局部变量中,可以使其明确地成为该函数和所有嵌套函数作用域的词法上下文的一部分。因此,在对“嵌套”的调用中,该内部函数将具有其自己的范围(它自己的this
值),但它仍然可以引用封闭范围中的变量“me”。
答案 1 :(得分:8)
常见的解决方法是使用闭包
sampleObject.prototype.getFoo = function() {
var _this = this;
var nested = function() {
return _this.foo;
}
return nested();
}
一些库添加了自动化
的方法答案 2 :(得分:7)
在您的示例中,“this”指的是窗口对象,因为在调用嵌套函数时没有指定另一个上下文,并且因为window.foo未定义而导致未查找。
您可以通过3种方式解决此问题。
sampleObject.prototype.getFoo = function() {
var _this = this;
var nested = function() {
return _this.foo;
}
return nested();
}
sampleObject.prototype.getFoo = function() {
var nested = function() {
return this.foo;
}.bind(this);
return nested();
}
SampleObject.prototype.getFoo = function() {
var nested = function() {
return this.foo;
};
return nested.call(this);
}
答案 3 :(得分:5)
使用arrow functions。它们自ECMAScript 6以来可用:
var sampleObject = function() {
this.foo = 123;
}
sampleObject.prototype.getFoo = function() {
var nested = () => { // Changed this line.
return this.foo;
}
return nested();
}
var test = new sampleObject();
window.alert(test.getFoo());

这是箭头功能的主要优点之一。您的案例在以下部分中进行了描述:No binding of this
。参考指出:
在箭头函数之前,每个新函数都定义了自己的
this
值[...] 箭头函数不会创建自己的this
上下文,因此this
具有封闭上下文中的原始含义。
答案 4 :(得分:4)
除了将其声明为var _this = this
之外,我还会看到代码正在执行var that = this
或var self = this
。
了解变量的范围很重要,因为它可能会产生意外结果。
答案 5 :(得分:1)
这是一个老问题,但为了完整起见,我给出了另一个解决方案。另一种方法涉及function binding。
sampleObject.prototype.getFoo = function() {
var nested = function() {
return this.foo;
}
return nested.bind(this)();
}
答案 6 :(得分:0)
这是一个关于JavaScript的已知疣。通常的模式是将它分配给外部函数中的另一个变量(通常是self),然后从内部函数访问self。这很有效。
答案 7 :(得分:0)
ES6的一种实现方法是使用Arrow Function。基本上,当您使用箭头功能时,它不会创建它自己的“ this”上下文。因此,使用“ this”将引用父函数的上下文。代码如下:
sampleObject.prototype.getFoo = function() {
const nested = () => {
return this.foo; //"this" refers to parent function's context
}
return nested;
}