2014-04-26 34 views
1

目前我使用下面的代碼來定義getter和setter方法我的課:object.defineProperty環路

Object.defineProperty(FPProject.prototype, 'name', { 
     get: function() { return this.get('name'); }, 
     set: function(aValue) {return this.set('name', aValue);} 
    }); 
    Object.defineProperty(FPProject.prototype, 'code', { 
     get: function() { return this.get('code'); }, 
     set: function(aValue) {return this.set('code', aValue);} 
    }); 
    Object.defineProperty(FPProject.prototype, 'clientName', { 
     get: function() { return this.get('clientName'); }, 
     set: function(aValue) {return this.set('clientName', aValue);} 
    }); 
    Object.defineProperty(FPProject.prototype, 'client', { 
     get: function() { return this.get('client'); }, 
     set: function(aValue) {return this.set('client', aValue);} 
    }) 

我認爲我可以優化這段代碼是這樣的:

var fields = ['name','code','clientName','client']; 

    for (var i = 0; i < fields.length; i ++) { 
     Object.defineProperty(FPProject.prototype, fields[i], { 
      get: function() { return this.get(fields[i]); }, 
      set: function(aValue) {return this.set(fields[i], aValue);} 
     }); 
    } 

但它不工作!我沒有控制檯錯誤,只是不能設置屬性...?

回答

3

其他兩個答案工作得很好(我upvoted他們),但我想我會補充說,這是一個地方數組迭代器方法派上用場,因爲使用它的任務創建一個函數閉包你操作它會自動爲您解決了這個問題索引:

['name','code','clientName','client'].forEach(function(item) { 
    Object.defineProperty(FPProject.prototype, item, { 
     get: function() { return this.get(item); }, 
     set: function(aValue) {return this.set(item, aValue);} 
    }); 
}); 

,當然,你必須要注意的.forEach()瀏覽器的兼容性需要IE9或更高或填充工具(如圖here)。這個設計模式被一個流行的第三方庫使用,因爲它是一種運行相同代碼的非常緊湊的方式,其中有幾個不同的值貫穿它。

+0

+1我一直忘記這個優秀的選擇。 –

3

當循環結束時,i變量將等於fields.length,稍後調用的set函數將使用此值。

嘗試使用閉合捕捉當前索引元素:

for (var i = 0; i < fields.length; i ++) { 
    (function (index) { 
      Object.defineProperty(FPProject.prototype, fields[index], { 
      get: function() { return this.get(fields[index]); }, 
      set: function(aValue) {return this.set(fields[index], aValue);} 
      }); 
    }(i)); 
} 
3

這是典型的封閉問題。你在循環中創建的函數有一個變量的持久參考i變量,而不是它的副本。因此,在調用訪問器函數時,ifields.length,因此它們從fields[i]獲得的值爲undefined

通常的解決辦法是設計器功能:

var fields = ['name','code','clientName','client']; 

for (var i = 0; i < fields.length; i ++) { 
    buildProperty(FPProject.prototype, fields[i]); 
} 

function buildProperty(obj, name) { 
    Object.defineProperty(obj, name, { 
     get: function() { return this.get(name); }, 
     set: function(aValue) {return this.set(name, aValue);} 
    }); 
} 

我總是讓這個一個不錯的,清晰的,獨立的功能,使A)我們不重新創建它的每一個迴路,和B)它更容易調試,理解和重用。

現在的訪問者關閉了通話的背景下buildProperty及其objname參數,這些參數不改變,所以他們是所謂的,當他們使用正確的name