在javascript中有一些我不理解的东西,并将样本问题分解为一个基本案例:
a = function () {
this.b = 5;
}
a.prototype.c = function () {
alert(this.b);
}
var d = new a();
var e = d.c; // how do I save a ref to the method including the context (object)??
d.c(); // 5 -> ok
e(); // undefined -> wtf??
那么为什么在上一个例子中没有上下文调用函数呢?我怎样才能用上下文来调用它?
提前致谢: - )
答案 0 :(得分:5)
d.c
就像一个未绑定的实例方法。您可以使用Function.prototype.bind
创建一个绑定到d
的新函数(.bind
的第一个参数是this
参数):
var e = d.c.bind(d);
或使用e
作为d
参数调用this
:
e.call(d);
答案 1 :(得分:2)
您需要使用该对象调用该方法以获得正确的上下文。所以:
var e = function() { return d.c(); };
在较新的浏览器中,您可以使用bind
method执行相同的操作:
var e = d.c.bind(d);
例如,在jQuery中,您可以在旧版浏览器中使用proxy
method:
var e = $.proxy(d.c, d);
答案 2 :(得分:1)
这是关于解析this
值。这可以通过以下方式解决:
myObject.something();//this in something is myObject
window.something();//this is window
button.onClick=function();//this when button is clicked is button
如何解决它已经给出了,如下例中使用setTimeout
传递回调是一个常见的陷阱var test = function () {
var me = this;// set reference to this
this.sayAgain=function(){
console.log("Hi, I am "+me.toString());
}
}
test.prototype.toString=function(){
return "test";
}
test.prototype.say = function () {
console.log("Hi, I am "+this.toString());
}
var t = new test();
setTimeout(t.say,50);//=window passing functon without ref to this
setTimeout(function(){
t.say();
},150);//=test passing ref with function
setTimeout(t.sayAgain,200);//=test using me as the saved this context
第二次超时将closure传递给setTimeout,如果你计划传递数百次回调,但只创建几个测试对象实例,那么最后一次执行(sayAgain)会执行稍好一点。
这是因为你在创建测试实例时创建了一个闭包,但是在将sayAgain作为回调传递时没有创建一个闭包,如果你创建了很多测试实例并且多次没有传递say
那么就删除this.me和this。 sayAgain从函数体中传递say
作为闭包。
您可以使用Function.prototype.bind,但在IE<< 8,我不确定它是否会在我的示例中使用t.say
创建一个闭包。