javascript Javascript回调丢失'this'
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10766407/
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
Javascript callbacks losing 'this'
提问by Anyone
I have an issuer where I lose the 'this' inside this 'object'. The output of the following piece of javascript gives me "some-id" and then "undefined". When I use 'this' inside a callback function, the scope goes out of the object and it cannot use 'this' anymore. How can I get the callback to use 'this' or at least have access to the object?
我有一个发行者,我在这个“对象”中丢失了“这个”。下面一段 javascript 的输出给了我“some-id”然后是“undefined”。当我在回调函数中使用 'this' 时,作用域超出对象并且不能再使用 'this'。如何让回调使用“this”或至少可以访问该对象?
Since I will make multiple objects, I won't be able to create a 'static' like storage. Please help this javascript n00b ;-)
由于我将创建多个对象,因此我将无法创建类似存储的“静态”。请帮助这个javascript n00b ;-)
here is my test code that you can use to reproduce my problem. What I would like to have is CheckBox.doSomething()
to return the value of this.id
which should match some-id
for this test case.
这是我的测试代码,您可以使用它来重现我的问题。我想要的是CheckBox.doSomething()
返回this.id
应与some-id
此测试用例匹配的值。
function CheckBox(input_id) {
this.id = input_id;
this.doSomething();
$('#some-element').click(this.doSomething);
}
Checkbox.prototype.doSomething = function() {
alert(this.input_id);
}
var some_box = new CheckBox('some-id');
some_box.doSomething();
$('#some-element').click();
edit: I can't even get this to work as I want it to:
编辑:我什至无法像我希望的那样工作:
function CheckBox2(input_id) {
this.id = input_id;
alert(this.id);
}
CheckBox2.prototype.doSomething = function() {
alert(this.input_id);
}
var some_box = new CheckBox2('some-id');
some_box.doSomething();
采纳答案by Esailija
function CheckBox(input_id) {
this.id = input_id;
this.doSomething = $.proxy( this.doSomething, this );
$('#some-element').click(this.doSomething);
}
The "javascript equivalent" of this is Function#bind
but that is not available in every browser and since it seems you are using jQuery I am using the jQuery equivalent $.proxy
这个“javascript等价物”是Function#bind
但不是在每个浏览器中都可用,因为看起来你正在使用jQuery,我正在使用jQuery等价物$.proxy
回答by georgebrock
Your problem is with this line: $('#some-element').click(this.doSomething);
您的问题出在这一行: $('#some-element').click(this.doSomething);
Why this is a problem
为什么这是一个问题
JavaScript methods don't know anything about the object that should be assigned to this
, it's set when the method is called either explicitly (with myFunction.call(obj)
) or implicitly (when called using obj.myFunction()
).
JavaScript 方法对应该分配给的对象一无所知this
,它在显式(使用myFunction.call(obj)
)或隐式(使用调用时)调用方法时设置obj.myFunction()
。
For example:
例如:
var x = {
logThis: function () {
console.log(this);
}
};
x.logThis(); // logs x
x.logThis.call(y); // logs y
var func = x.logThis;
func(); // logs window: the fallback for when no value is given for `this`
In your case, you're passing this.doSomething
to jQuery, which is then explicitly calling it with the element that was clicked as the value of this
. What's happening is (a slightly more complex version of) this:
在您的情况下,您将传递this.doSomething
给 jQuery,然后它会使用被单击的元素作为 的值显式调用它this
。发生的事情是(稍微复杂的版本)这个:
var callback = this.doSomething;
callback.call(anElement, anEvent);
The solution
解决方案
You need to make sure that doSomething
is called with the right value of this
. You can do that by wrapping it in another function:
您需要确保doSomething
使用正确的this
. 您可以通过将其包装在另一个函数中来做到这一点:
var cb = this;
$('#some-element').click(function() {
return cb.doSomething();
});
jQuery provides a proxy
function lets you do this more simply:
jQuery 提供了一个proxy
函数让你更简单地做到这一点:
$('#some-element').click(jQuery.proxy(this.doSomething, this));
回答by wortwart
Others have already explained the causes of the problem and how to fix it with jQuery. What's left is how you fix it with standard JavaScript. Instead of ...
其他人已经解释了问题的原因以及如何使用 jQuery 修复它。剩下的就是如何使用标准 JavaScript 修复它。代替 ...
$('#some-element').click(this.doSomething);
... you write:
... 你写:
document.getElementById('some-element').addEventListener('click', this.doSomething.bind(this));
This changes the context of this
inside doSomething
. You can also do that with anonymous functions - instead of ...
这改变了this
inside的上下文doSomething
。您也可以使用匿名函数来做到这一点 - 而不是......
$('#some-element').click(function(event) {
console.log(this);
});
... you write:
... 你写:
document.getElementById('#some-element').addEventListener('click', (function(event) {
console.log(this);
}).bind(this));
That has been very useful to me in projects with lots of callbacks, e.g. in Node.js (where you don't have to care about outdated browsers).
这对我在具有大量回调的项目中非常有用,例如在 Node.js 中(您不必关心过时的浏览器)。
Edit: getElementById()
and addEventListener()
instead of $(...).click(...)
.
编辑:getElementById()
而addEventListener()
不是$(...).click(...)
.