跳到主要内容

JavaScript Object 拷贝

· 阅读需 2 分钟
givebest

创建一个对象

let obj1 = {
a: 1,
b: 2,
c: 3,
d: {
e: 4,
},
f: function () {
return this.a;
},
};

/*
Object.prototype.__proto__
改变一个对象的 [[Prototype]] 属性。
已经废弃,建议只使用 Object.setPrototypeOf/Object.getPrototypeOf,
或者 Object.create
*/
obj1.__proto__.g = 5;

/*
Object.setPrototypeOf() 设置一个指定的对象的原型(内部[[Prototype]]属性)到另一个对象或 null。
性能缓慢,应避免使用。
*/
Object.setPrototypeOf(obj1, { h: 6 });
console.warn("------obj1--------");
console.log(obj1.a, obj1.g, obj1.h, obj1.f()); // 1 5 6 1

拷贝

浅拷贝

JSON

  • Function 不能拷贝
  • Object.setPrototypeOf 设置的对象不能拷贝
let obj2 = JSON.parse(JSON.stringify(obj1));
// obj1.a = '0'
console.warn("------obj2--------");
console.log(obj2.a, obj2.g, obj2.h); // 1 5 undefined
try {
console.log(obj2.f());
} catch (error) {
console.log("obj2.f() 不能访问");
}
// obj2.f() 不能访问

深拷贝

For in & hasOwnProperty

function cloneObj1(obj) {
if (Object.prototype.toString.call(obj) !== "[object Object]") return obj;

let tempObj = {};
// let tempObj = obj.constructor();
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
tempObj[key] = obj[key];
}
}
return tempObj;
}

let obj3 = cloneObj1(obj1);
obj1.a = 3;
console.warn("------obj3--------");
console.log(obj3.a, obj3.g, obj3.h, obj3.f()); // 1 5 undefined 1

Object.assign()

将所有可枚举属性的值从一个或多个源对象复制到目标对象。

let obj4 = Object.assign({}, obj1);
obj1.a = 4;
console.warn("------obj4--------");
console.log(obj4.a, obj4.g, obj4.h, obj4.f()); // 3 5 undefined 3

继承

Object.create()

创建新对象,使用现有的对象来提供新创建的对象的proto

let obj5 = Object.create(obj1);
obj1.a = 5;
// obj5.a = 'x';

console.warn("------obj5--------");
// obj5 继承 obj1,obj1.a 的值改变, obj5 也改变
console.log(obj5.a, obj5.g, obj5.h, obj5.f()); // 5 5 6 5

转载请注明出处: https://blog.givebest.cn/javascript/2020/06/27/javascript-object-clone.html