面試中,你們常常會遇到,面試官讓你講述什麼是深拷貝,什麼是淺拷貝,如何實現深拷貝,如何實現淺拷貝。這都是一下面試中常常遇到的問題。咱們若是不經能說出,還能寫出,那你就很叼了。 面試
建立一個新對象,這個對象有着原始對象屬性值的一份精確拷貝。若是屬性是基本類型,拷貝的就是基本類型的值,若是屬性是引用類型,拷貝的就是引用類型的指針。若是原對象改變了這個指針,拷貝對象也會受影響。瀏覽器
將 B 對象拷貝到 A 對象中,但不包括 B 裏面的子對象。淺拷貝只複製一層對象的屬性,並不包括對象裏面的爲引用類型的數據。 bash
Object.assign();在不少的文章中,有說起到Object.assign()是一個深拷貝,你們請注意一下,它是一個淺拷貝。這裏稍微扯遠一點,在面試中,若是讓你實現一個Object.assign();咱們該怎麼作了。代碼以下。異步
// 判斷是否支持assign屬性
if (Object.assign == null) {
Object.defineProperty(Object, 'assignMy', {
value: function(target) {
if (target == null) {
throw new TypeError('xxxx');
}
var newObj = Object(target);
for (var index = 1; index < arguments.length; index++) {
var nextSource = arguments[index];
if (nextSource != null) {
for (var source in nextSource) {
if(Object.prototype.hasOwnProperty.call(nextSource, source)) {
newObj[source] = nextSource[source];
}
}
}
}
return newObj;
},
writable: true,
configurable: true,
enumerable: false
});
}
複製代碼
function list() {
return Array.prototype.slice.call(arguments);
}
var m = {a: 1, b: 2, c: { d: 3 }};
var list1 = list(1, 2, 3, m);
m.c.d = 5;
console.log(list1);
複製代碼
將一個對象衝內存中徹底的拷貝出來,分配一個新的內存區域存放新的對象,且修改對象不會影響到原來的對象。函數
將 B 對象拷貝到 A 對象中,包括 B 裏面的子對象。它不只將原對象的各個屬性逐個複製出去,並且將原對象各個屬性所包含的對象也依次採用深複製的方法遞歸複製到新對象上。post
function clone(obj) {
return new Promise(resolve => {
const {port1, port2} = new MessageChannel();
port2.onmessage = ev => resolve(ev.data);
port1.postMessage(obj);
});
}
複製代碼
function deepClone(target) {
function isObj(o) {
return (typeof o === 'object' || typeof o === 'function') && o !== null;
}
if (isObj(target)) {
let cloneTarget = Array.isArray(target) ? [] : {};
for (const key in target) {
cloneTarget[key] = deepClone(target[key]);
}
return cloneTarget;
} else {
return target;
}
}
var target1 = {
field1: 1,
field2: undefined,
field3: {
child: 'child'
},
field4: [2, 4, 8],
field5: function() {},
field6: Symbol('field6')
};
console.time('clone');
var obj = deepClone(target1);
console.log(obj);
console.timeEnd('clone');
複製代碼
function deepClone(target, map = new Map()) {
function isObj(o) {
return (typeof o === 'object' || typeof o === 'function') && o !== null;
}
if (isObj(target)) {
let cloneTarget = Array.isArray(target) ? [] : {};
if (map.get(target)) {
return map.get(target);
}
map.set(target, cloneTarget);
// 這裏還可使用while來提升性能
for (const key in target) {
cloneTarget[key] = deepClone(target[key], map);
}
return cloneTarget;
} else {
return target;
}
}
var target1 = {
field1: 1,
field2: undefined,
field3: {
child: 'child'
},
field4: [2, 4, 8]
};
target1.target1 = target1;
console.time('clone');
var obj = deepClone(target1);
console.log(obj);
console.timeEnd('clone');
複製代碼