2011-05-05 109 views
0

我有一些功能,只有返回值,如果在DOM一些潜在的“东西”有变化,像这样:如果计算机VAR x处理不当改变持久性的JavaScript函数对象中

function getFoo() { 

     if (typeof this.prev === "undefined") { 
      this.prev = null; 
     } 
// calculate x 

     if (x != this.prev) { 
      this.prev = x; 
     return this.prev; 
     } else { 
     return; 
     } 
    } 

foo返回None 。这在从控制台调用时似乎工作正常。

接着,我在对象包裹此,我就可以顺序地调用类似的功能:

function bar() { 
    this.plugins = { 
     foo: getFoo 
    }; 

    for (var attr in this.plugins) { 
     if (this.plugins.hasOwnProperty(attr)) { 
      console.log(this.plugins[attr]()); 
     } 
    } 

奇怪的是,当我现在请bar(),底层功能(如getFoo)总是返回值 - - 即使dom中的潜在东西没有改变。看起来功能在使用时被破坏(在plugin对象中) - 我如何坚持这些?

+0

你可以举一个例子,你叫什么时候/你怎么叫bar()? – Matt 2011-05-05 15:11:33

+1

仅供参考,函数*总是*返回一个值;只是'return'将返回'undefined'。 – 2011-05-05 15:12:03

+1

你的描述是非常缺乏的,没有显示更多的代码和更多的上下文,几乎不可能知道'this'在所有这些函数中具有什么上下文。我敢打赌,我的最低收益是这是一个“范围问题”。尝试将这些函数的调用改为'.call(this)' – davin 2011-05-05 15:18:23

回答

1

那么,当你调用bar(),它调用

this.plugin.getFoo(); 

所以thisgetFoo将引用this.plugins

this.plugins = { 
    foo: getFoo 
}; 

老实说,你的结构似乎相当混乱:

你每次调用bar()时间初始化this.plugin一个新的对象。你知道this里面的bar()函数是指window对象吗?你用这个“污染”全局命名空间。如果您直接打电话,则与getFoo相同。

也许你应该有更多这样的事情:

var bar = { 
    plugins: {foo: getFoo}, 
    run: function() { 
     for (var attr in this.plugins) { 
      if (this.plugins.hasOwnProperty(attr)) { 
       console.log(this.plugins[attr]()); 
      } 
     } 
    } 
}; 

的您可以拨打:

bar.run(); 

具有持久性和私有数据之间的函数调用的另一种方法是使用关闭:

var getFoo = (function() { 
    var prev = null; 

    return function(x){ 
     if (x != prev) { 
      prev = x; 
      return prev; 
     } 
    } 
}()); 

这里由直接函数返回的函数关闭了prev。无论您分配的地点是getFoo,它将始终访问prev,并且不会覆盖其他某个范围内的其他prev变量。

我认为当您将x传递给该函数时也会更好。

+0

谢谢 - 它很难解释整个上下文,但我认为函数closure重构将起作用! – malangi 2011-05-05 15:33:25

1

因此,每次调用“bar()”时,都会覆盖对象的插件属性。只要把一个简单的检查,在重新定义之前的插件属性,像这样:

function bar() { 
    if (typeof this.plugins === "undefined") { 
    this.plugins = { 
     foo: getFoo 
    }; 
    } 

    for (var attr in this.plugins) { 
     if (this.plugins.hasOwnProperty(attr)) { 
      console.log(this.plugins[attr]()); 
     } 
    } 
...