deepClone, extend, 深克隆物件和Object.assign(ES6)
在看 you might not need jQuery的時候(外網打不開,這是個部落格園轉過來的),看到了$.extend函式來拷貝某個物件。測試了一下原文程式碼,居然複製不到深層的。原始碼如下:
var deepExtend = function(out) {
out = out || {};//問題就出在這裡!
for (var i = 1; i < arguments.length; i++) {
var obj = arguments[i];
if (!obj)
continue;
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
if (typeof obj[key] === 'object')
deepExtend(out[key], obj[key]);
else
out[key] = obj[key];
}
}
}
return out;
};
deepExtend({}, objA, objB);
這裡雖然直接對out賦值了,但可能出現的情況是,原始的target物件容器中(第一個引數,即Out),out[key]為undefined,那麼如果確定out[key]的型別為物件的情況下,才是指向同一個物件,否則並沒有改變out[key]的值。
修改程式碼如下,將這一步提到前面,同時潤色程式碼增加報錯資訊:
function extend(out){
if(!out){
console.error('where is your container ?')
}
var objs = [].slice.call(arguments,1)
if(objs.length > 0){
objs.forEach(function(item,index){
if(typeof item !== 'object'){
console.error('item' + index + ' is no valid arguments, expected to be object')
}
else {
for(var key in item){
if(item.hasOwnProperty(key)){
if(typeof item[key] === 'object'){
out[key]= out[key] || {} // 這步是最重要的!
extend(out[key],item[key])
}
else{
out[key] = item[key]
}
}
}
}
})
}
else{
console.error('no objs to be copy')
}
return out;
}
var output = extend({a:{c:2},f:'fuck'},{a:1},{
b:{
lala:'name'
}
})
這樣就可以達到深克隆的目的了。當然除了JQuery, zepto、 Lodash、underScore、Prototype等庫都實現了這個工具。ES6中的Object.assign也原生提供了相應的功能。
Object.assign() 方法值能複製可列舉、本身的屬性(enumerable and own properties), 它用在引用源上使用get方法,在目標容器上使用set方法,引發了getters、setters。因此,如果在融合的源物件含有getter的話,會不適用。如果要複製屬性的定義,包括其可列舉性,應該使用Object.getOwnPropertyDescriptor()和Object.defineProperty()。
對深克隆,不可使用Object.assign() 方法,因為它只會複製物件的引用而不是新建一個物件。最簡單的深克隆方法某過於此,但只能複製可列舉型別的。
let target = JSON.parse(JSON.stringify(source))
因此,對深克隆,最好還是用extend方式層層遞迴,直到把源物件的屬性拆到不是物件而是plain value為止。
相關文章
- JavaScript深層克隆物件JavaScript物件
- js之物件深淺克隆JS物件
- 原生js實現物件的深克隆以及淺克隆JS物件
- java深克隆(深拷貝)和淺克隆(淺拷貝)Java
- vue陣列的深克隆和淺克隆Vue陣列
- 三目運算、物件克隆、深拷貝和淺拷貝物件
- CoffeeScript攻略2.1:克隆物件(深複製)物件
- ES6時代,你真的會克隆物件嗎?物件
- js中深克隆與淺克隆JS
- ES6時代,你真的會克隆物件嗎(二)物件
- es6完全深複製一個物件物件
- js 淺拷貝(淺複製、淺克隆)、深拷貝(深複製、深克隆)JS
- ES6中Object.assign() 方法Object
- JAVA 基礎 – clone淺克隆與深克隆Java
- JAVA 基礎 - clone淺克隆與深克隆Java
- js deep clone 深克隆JS
- 深入理解Java的淺克隆與深克隆Java
- ES6高階函式Array.reduce()和Object.assign()函式Object
- 使用c#強大的表示式樹實現物件的深克隆C#物件
- 前端戰五渣學JavaScript——深克隆(深拷貝)前端JavaScript
- $.extend()和$.fn.extend()區別
- ES6 的Object.assign(target, source_1, ···)Object
- js深度克隆物件JS物件
- 物件如何深度克隆物件
- javascript 深度克隆物件JavaScript物件
- 什麼要使用克隆、如何實現克隆物件、序列化與反序列實現克隆的好處、深拷貝與淺拷貝物件
- $.extend()和$.fn.extend()函式用法函式
- JAVA設計模式 2【建立型】原型模式的理解與使用、理解淺克隆和深克隆Java設計模式原型
- Java中的物件“克隆”Java物件
- js物件的深度克隆!JS物件
- js克隆一個物件JS物件
- 理解jquery的$.extend()、$.fn和$.fn.extend()jQuery
- JS型別判斷、物件克隆、陣列克隆JS型別物件陣列
- 物件深拷貝和淺拷貝物件
- 聊聊物件深拷貝和淺拷貝物件
- 在 JavaScript 中如何克隆物件?JavaScript物件
- 從JDK角度看物件克隆JDK物件
- JS物件深度克隆/複製JS物件