2013-07-23 87 views
1

标题的道歉,但没有简洁的方式。我正在研究下面的代码,它旨在将一组计数器链接在一起,形成一个大的代码。建立一个时钟或其他。将对象函数传递给对象构造函数

function subcounter(max, name, trigger) { 
    this.index = 0; 
    this.trigger = trigger; 
    this.name = name; 

    this.tick = function() { 
     this.index++; 
     if (this.index==max) { 
      this.index=0; 
      this.trigger(); 
     } 
    } 

    this.show = function() { 
     alert(this.name+' triggered'); 
    } 
} 

y = new subcounter(2,'y',function(){alert('finished')}); 
x = new subcounter(2,'x',y.tick); 

for (var index = 0; index < 12; index++) { 
    alert ([x.index, y.index]); 
    x.tick(); 
} 

这不起作用。为了调试我代替上面的一行:

x = new subcounter(2,'x',y.show); 

而且发现,“X触发”显示,而不是“Y触发”,这是我所期望的。这里发生了什么? (在Firefox中试过)。


感谢您的回答或指向我的文档this。然而,我的大脑仍然无法理解函数如何作用于一个对象实例:'y.show'可以在不同的对象实例上解析该函数​​。

的答案似乎是:

x = new subcounter(2,'x',function() {y.tick();}); 

但我仍想明白为什么预期原不起作用。

+0

阅读'this':https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this?redirectlocale=en-US&redirectslug=JavaScript%2FReference%2FOperators%2Fthis – haim770

回答

2

应该是这样

function subcounter(max, name, trigger) { 
    var that = this; 
    this.index = 0; 
    this.trigger = trigger; 
    this.name = name; 

    this.tick = function() { 
     that.index++; 
     if (that.index==max) { 
      that.index=0; 
      that.trigger(); 
     } 
    } 

    this.show = function() { 
     alert(that.name+' triggered'); 
    } 
} 

否则JavaScript的本地作用域将有this包含对外部情境this参考(即,你的情况x.this)的内部函数。

Here是一篇详细介绍javascript本地范围功能的文章,但这只是我得到的第一个结果,这是一个很常见的问题。

+0

我很乐意接受这个答案。除非它不起作用。我仍然'x触发'。 –

+0

很奇怪:我用我的修改过的代码(和'alert's替换为'console.log')在http://jsfiddle.net/H5Bs3/创建了一个小提琴,它似乎在工作。 – Raibaz

+0

我看到那里是正确的。但是Firefox/IE都工作不正确。 –

1

从我所看到的,它具有与“本”的价值将是一个函数里面做什么。

函数'this'的内部将是调用函数的对象的值。

当你调用this.trigger()时,它现在是对象'x'。因此,触发功能,即“秀”,

this.name will be same as x.name 

为了获得在y对象的值,通过“Y”对象本身并调用来自该对象的显示功能内。

function subcounter(max, name, trigger, methodName) { 
    this.index = 0; 
    this.trigger = trigger; 
    this.name = name; 

    this.tick = function() { 
     this.index++; 
     if (this.index==max) { 
      this.index=0; 
      this.trigger[methodName](); 
     } 
    } 

    this.show = function() { 
     console.log(this.name+' triggered'); 
    } 
} 

y = new subcounter(2,'y',function(){alert('finished')}); 
x = new subcounter(2,'x',y, "show"); 
+0

这工作。然而它不灵活。正如你所看到的,我希望能够传递任何函数来触发。 –

+0

@ guillermo-phillips我已经更新了我的答案。现在您可以传递对象和方法名称来调用。 – blessenm