为什么这不被认为是一种功能?

时间:2013-05-21 16:03:43

标签: javascript

我的对象中有这个功能:

var time = {

    warps : 3,
    warpCounter : 50,

    warp : function(){
        if (this.warps > 0){
            this.warps--;
            this.warpLoop = 50;
            this.warpLoop(); 
        }
    },

    warpLoop : function(){
       setTimeout(function () {
          this.increment();              
          if (warpCounter--){
            this.warpLoop();
          }else{
            if(this.warps > 0){
              htmlInteraction.enableButton('warp-button');
            }
          }
       }, 100);
    },

};

当我尝试从另一种方法(使用this.warpLoop())调用它时,我得到:

Uncaught TypeError: Property 'warpLoop' of object #<Object> is not a function 

为什么会这样?

2 个答案:

答案 0 :(得分:5)

setTimeout中的这个上下文发生了变化,你可以使用闭包来保持这个上下文。

var test={
warpLoop : function(){
   var me=this;//set closure to get the right this context
   setTimeout(function () {
     console.log("this is:",this); // is window
     console.log("me is:",me); // is test
     // can call me.warpLoop() but not this.warpLoop()
   }, 100);
}
}
test.warpLoop();

您的代码可能如下所示:

var time = {

    warps : 3,
    warpCounter : 3,

    warp : function(){
        if (this.warps > 0){
            this.warps--;
            this.warpLoop = 50;
            this.warpLoop(); 
        }
    },

    warpLoop : function(){
       //the setTimeout calls me.warpCounter not this.warpCounter
       // wich is the same as window.warpCounter since the next
       // line is not part of the setTimeout execution you can
       // use this
       console.log("warpLoop called,warpCounter is",this.warpCounter);
       var me=this;
       setTimeout(function () {
          //me.increment();              
          if (me.warpCounter--){
            me.warpLoop();
          }else{
            if(me.warps > 0){
              //htmlInteraction.enableButton('warp-button');
            }
          }
       }, 100);
    },

};
time.warpLoop();

答案 1 :(得分:3)

JavaScript中的this值不是词法定义的。它由调用函数的方式定义。

一个典型的解决方法是将this的值存储在封闭范围内的变量中,然后在内部范围中引用它。

var that = this;

setTimeout(function() {
    that.whatever()
}, 1000)

虽然您也可以使用this将外部Function.prototype.bind()值绑定到回调,但您似乎有一个.increment()方法不会抛出错误。所以绑定可能会破坏它。

相关问题