Javascript 原型函数内的函数中的“this”
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4700880/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
'this' in function inside prototype function
提问by pimvdb
I basically have an object, extended with a function through its prototype. Inside that function, another function exists, however when using this
in this nested function, it does not seem to refer to the object, but the function.
我基本上有一个对象,通过它的原型扩展了一个函数。在那个函数内部,存在另一个函数,但是this
在这个嵌套函数中使用时,它似乎不是指对象,而是指函数。
For example,
例如,
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
The this.foo
does not refer to the 123 value, but is undefined as this refers to the nested function, in which no foo
exists. How can I access the 123 value from the nested function?
Thethis.foo
不是指 123 值,而是未定义,因为 this 指的是嵌套函数,其中 nofoo
存在。如何从嵌套函数访问 123 值?
采纳答案by Pointy
sampleObject.prototype.getFoo = function() {
var me = this;
var nested = function() {
return me.foo;
}
return nested;
}
By saving the value of this
in a local variable, you make it explicitly part of the lexical context for that function and for all nested function scopes. Thus, on the call to "nested", that inner function will have its own scope (it's own this
value), but it can still refer to the variable "me" in the enclosing scope.
通过将 的值保存this
在局部变量中,您可以使其明确成为该函数和所有嵌套函数作用域的词法上下文的一部分。因此,在调用“nested”时,该内部函数将有自己的作用域(它自己的this
值),但它仍然可以引用封闭作用域中的变量“me”。
回答by Hemlock
The common work around for that is to use closure
常见的解决方法是使用闭包
sampleObject.prototype.getFoo = function() {
var _this = this;
var nested = function() {
return _this.foo;
}
return nested();
}
Some libraries add methods to automate this
一些库添加了自动执行此操作的方法
- Prototype adds Function.bind (http://prototypejs.org/doc/latest/language/Function/prototype/bind/)
- Ext adds function.createDelegate (http://www.sencha.com/learn/Manual:Utilities:Function#createDelegate)
- Javascript 1.8.5 adds function.bind (https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind)
- Prototype 添加 Function.bind ( http://prototypejs.org/doc/latest/language/Function/prototype/bind/)
- Ext 添加 function.createDelegate ( http://www.sencha.com/learn/Manual:Utilities:Function#createDelegate)
- Javascript 1.8.5 添加了 function.bind ( https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind)
回答by Marius Lazar
In your example "this" refers to the window object because you didn't specify another context when you call the nested function and you get undefind because window.foo is undefined.
在您的示例中,“this”指的是 window 对象,因为您在调用嵌套函数时没有指定另一个上下文,并且因为 window.foo 未定义而得到 undefind。
You can fix this in 3 ways.
您可以通过 3 种方式解决此问题。
1 - Use a variable to store the outside this - most used method
1 - 使用变量存储外部 this - 最常用的方法
sampleObject.prototype.getFoo = function() {
var _this = this;
var nested = function() {
return _this.foo;
}
return nested();
}
2 - Use the bind method which bind the outer "this" to the inner one
2 - 使用绑定方法将外部“this”绑定到内部
sampleObject.prototype.getFoo = function() {
var nested = function() {
return this.foo;
}.bind(this);
return nested();
}
3 - Use the call method which can pass the context to the function
3 - 使用可以将上下文传递给函数的调用方法
SampleObject.prototype.getFoo = function() {
var nested = function() {
return this.foo;
};
return nested.call(this);
}
回答by totymedli
tl;dr
tl;博士
Use arrow functions. They are available since ECMAScript 6:
使用箭头函数。它们从 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());
Explanation
解释
This is one of the main advantages of arrow functions. Your case is described in the section: No binding of this
. The refference states:
这是箭头函数的主要优点之一。您的情况在以下部分中进行了描述:没有this
. 参考文献指出:
Until arrow functions, every new function defined its own
this
value [...] An arrow function does not create its ownthis
context, sothis
has the original meaning from the enclosing context.
在箭头函数之前,每个新函数都定义了自己的
this
值 [...] 箭头函数不会创建自己的this
上下文,因此this
具有来自封闭上下文的原始含义。
回答by Lionel Chan
Apart from declaring it to var _this = this
, I also see codes doing var that = this
or var self = this
.
除了将其声明为var _this = this
,我还看到代码在执行var that = this
或var self = this
。
Knowing your variable's scope is important as it might raises unexpected result.
了解变量的作用域很重要,因为它可能会产生意想不到的结果。
回答by c.bear
This is an old question, but I give another solution for the sake of completeness. Another approach involves function binding.
这是一个老问题,但为了完整起见,我给出了另一个解决方案。另一种方法涉及函数绑定。
sampleObject.prototype.getFoo = function() {
var nested = function() {
return this.foo;
}
return nested.bind(this)();
}
回答by Matt Goodwin
An ES6 way of doing this would be to use an Arrow Function. Basically, when you use an arrow function, it does not create it's own "this" context. So, using "this" would then refer to the parent function's context. Here's how the code would look:
ES6 的一种方法是使用箭头函数。基本上,当您使用箭头函数时,它不会创建自己的“this”上下文。因此,使用“this”将引用父函数的上下文。下面是代码的样子:
sampleObject.prototype.getFoo = function() {
const nested = () => {
return this.foo; //"this" refers to parent function's context
}
return nested;
}
回答by Raph Levien
This is a known wart on JavaScript. The usual pattern is to assign this to another variable (often self) in the outer function, then access self from the inner funtction. This works.
这是 JavaScript 上的一个众所周知的问题。通常的模式是将 this 分配给外部函数中的另一个变量(通常是 self),然后从内部函数访问 self。这有效。