传递函数,包括javascript中的上下文
在javascript中有一点我不理解,并将一个示例问题分解为一个基本情况:传递函数,包括javascript中的上下文,javascript,Javascript,在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 (obje
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??
那么,在上一个示例中,为什么在没有上下文的情况下调用函数呢?我怎么能用上下文来称呼它呢
提前感谢:-)
d.c
就像一个未绑定的实例方法。您可以使用Function.prototype.bind
创建绑定到d
的新函数(.bind
的第一个参数是此
参数):
或者使用d
作为此
参数调用e
:
var e = d.c.bind(d);
e.call(d);
您需要使用对象调用该方法以获得正确的上下文。因此:
var e = function() { return d.c(); };
在较新的浏览器中,您可以使用来执行相同的操作:
var e = d.c.bind(d);
例如,在jQuery中,您还可以在较旧的浏览器中使用:
var e = $.proxy(d.c, d);
它是关于解析
这个值的。这可通过以下方式解决:
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
第二个超时传递到setTimeout,如果您计划通过say回调数百次,但只创建两个测试对象实例,那么最后一个(sayreach)的实现的性能会稍好一些
这是因为您在创建测试实例时创建了闭包,但在将sayReach作为回调传递时没有创建闭包,如果您创建了多个测试实例,并且没有多次传递say
,则从函数体中删除This.me和This.sayReach,并将say
作为闭包传递
您可以使用,但IE<8不支持它,我不确定它是否会像我的示例中使用t那样创建闭包