2017-08-19 103 views
4

我讀上Object.assign()MDN docs和跨一個短語來了,我不明白:可憐的用例 - 簡單的例子

的Object.assign()方法僅複製可枚舉並擁有從源對象到目標對象的屬性。它使用源上的[[Get]]和目標上的[[Set]],所以它會調用getter和setter。因此它分配屬性而不是複製或定義新屬性。如果合併源包含getter,這可能會使它不適合將新屬性合併到原型中。爲了將屬性定義(包括其可枚舉性)複製到原型中,應該使用Object.getOwnPropertyDescriptor()和Object.defineProperty()。

特別是這一行:

這可能使其不適合用於合併新特性爲原型,如果合併源包含干將。

我不完全確定什麼是一個很好的例子是倡導反對使用Object.assign

回答

5

A getter是用於返回屬性值的屬性的訪問器函數。這是一個getter對象的樣子:

var obj = { 
 
    get example() { 
 
     console.log("getter was called"); 
 
     return Math.floor(Math.random() * 100); 
 
    } 
 
}; 
 
console.log(obj.example); 
 
// Note no() ---------^

注意,當我們讀到example屬性的值,函數獲取運行,即使它看起來並不像一個函數呼叫。

MDN文檔的那部分內容是,Object.assign調用該getter,它不會在目標對象上創建一個等效的getter。所以:

var obj = { 
 
    get example() { 
 
     console.log("getter was called"); 
 
     return Math.floor(Math.random() * 100); 
 
    } 
 
}; 
 
var obj2 = Object.assign({}, obj); // calls getter 
 
console.log(obj2.example);   // just has a simple value 
 
console.log(obj2.example);   // same value, no call 
 
console.log(obj2.example);   // same value, no call

objexample酒店有一個getter,但obj2example屬性只是一個簡單的價值屬性。 Object.assign沒有複製吸氣劑,它只是抓住吸氣劑的當前值並將其分配給obj2.example

可以副本干將,只是不能與Object.assign

function copyProperties(target, source) { 
 
    Object.getOwnPropertyNames(source).forEach(name => { 
 
     Object.defineProperty(
 
      target, 
 
      name, 
 
      Object.getOwnPropertyDescriptor(source, name) 
 
     ); 
 
    }); 
 
    return target; 
 
} 
 
var obj = { 
 
    get example() { 
 
     console.log("getter was called"); 
 
     return Math.floor(Math.random() * 100); 
 
    } 
 
}; 
 
var obj2 = copyProperties({}, obj); // calls getter 
 
console.log(obj2.example);   // calls getter 
 
console.log(obj2.example);   // calls getter 
 
console.log(obj2.example);   // calls getter

當然,如果吸氣不是設計對象之間進行復制(例如,如果example的明確使用obj),你可能會得到意想不到的結果。

+0

這非常有道理,謝謝。但是如果我爲'source'對象添加了特定的非枚舉屬性,並且我正在使用'getOwnPropertyNames'的最後一個示例呢?即使那些我們使用這種方法來獲得不可枚舉的getter和setter,它也會拿起其他任何非枚舉類型(比如'length',如果它是一個數組對象的話)。所以我必須在自定義'copyProperties'方法中手動排除它們,是的? – qarthandso

+0

@qarthandso:我剛剛幾乎隨意使用了'getOwnPropertyNames',想知道是否有人想複製getter和setter等,他們可能也想複製非枚舉屬性。 (按照這個邏輯,我可能應該也包含'getOwnPropertySymbols';但它只是一個小例子。)如果你想複製屬性,但堅持可枚舉的屬性,使用'Object.keys',它只給你自己的,可枚舉屬性。 –