2011-05-05 148 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]()); 
     } 
    } 
...