3

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??

那么为什么在上一个示例中调用函数时没有上下文?我怎么能在上下文中调用它?

提前致谢 :-)

4

3 回答 3

6

d.c就像一个未绑定的实例方法。您可以使用Function.prototype.bind创建一个绑定到的新函数d(第一个参数.bindthis参数):

var e = d.c.bind(d);

或者调用ewithd作为this参数:

e.call(d);
于 2013-07-08T00:42:51.820 回答
2

您需要使用该对象调用该方法以获取正确的上下文。所以:

var e = function() { return d.c(); };

在较新的浏览器中,您可以使用该bind方法执行相同操作:

var e = d.c.bind(d);

例如,在 jQuery 中,您也可以在旧浏览器中使用该proxy方法

var e = $.proxy(d.c, d);
于 2013-07-08T00:44:12.780 回答
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

第二个超时将闭包传递给 setTimeout,如果您计划通过数百次 say 回调但只创建几个测试对象实例,那么最后一个 (sayAgain) 的实现会稍微好一些。

这是因为您在创建测试实例时创建了一个闭包,但在将 sayAgain 作为回调传递时没有创建闭包,如果您创建了许多测试实例并且不会通过say那么多次,则从函数体中删除 this.me 和 this.sayAgain 并传递say为一个关闭。

您可以使用Function.prototype.bind但它在 IE < 8 中不受支持,我不确定它是否会像我的示例中使用t.say.

于 2013-07-08T01:38:00.960 回答