原生的Object.assign(target, src)
方法來實現(xiàn)淺拷貝:Object.assign({},ab)
擴展運算符:{...ab}
常用的深拷貝:
let newObj = JSON.parse(JSON.stringify(oldObj))
(只適合普通數(shù)據(jù)類型找前,怕環(huán)形對象,怕function 等一些特定數(shù)據(jù)結(jié)構(gòu))
var ov={
a:{
b:{
c:{arr:[1,2,3]}
}
}
}
var ob = JSON.parse(JSON.stringify(ov))
// a:b:c:arr: (3) [1, 2, 3]
var obj2 = { // 環(huán)形對象
to:obj1
}
obj1.to = obj2;
// 這種就會報錯
深拷貝對象和數(shù)組時:
function deepClone(obj) {
if (!obj || typeof obj !== 'object') return
let newObj = Array.isArray(obj) ? [] : {}
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
newObj[key] =
typeof obj[key] === 'object' ? deepClone(obj[key]) : obj[key]
}
}
return newObj
}
對于所有的對象類型深拷貝:
let obj1 = {
// typeof 數(shù)組|對象 => 'object'
// Array.isArray()
arr: [1, 2, 3],
arrayOfObjs: [{ c: 5 }, { d: 6 }],
date: new Date(),
object: { val: 4 },
// 增加一個屬性
fn: function () { // typeof fn ===> 'function'
return 5;
},
set: new Set([7, 8, 9, { e: 10 }]),
map: new Map([
[11, 'f'],
[12, 'g']
]),
reg: /[h-z]/
};
let wm = new WeakMap();
function deepClone(obj) {
// 基本數(shù)據(jù)類型 和函數(shù)處理, null
// function f (){}
// typeof f => 'function'
if (obj === null || typeof obj !== 'object') {
// 直接返回
return obj
}
// 如果緩存中已經(jīng)存在該對象則不繼續(xù)操作 WeakMap
if (wm.has(obj)) {
return wm.get(obj)
}
// 處理Map
// 處理Set
// 處理RexExp
if (obj instanceof Map) {
var tmp = new Map();
wm.set(obj,tmp);
for (var values of obj) {
var key = values[0];
var val = values[1];
tmp.set(key, deepClone(val));
}
return tmp;
} else if (obj instanceof Set) {
var tmp = new Set();
wm.set(obj,tmp);
for (var val of obj) {
tmp.add(deepClone(val));
}
return tmp;
} else if (obj instanceof RegExp) {
var tmp = new RegExp(obj);
wm.set(obj,tmp);
return tmp;
} else {
// 處理數(shù)組、對象搁料、Date
var tmp = new obj.constructor();
wm.set(obj,tmp);
for(var key in obj){
tmp[key] = deepClone(obj[key]);
}
return tmp;
}
}
Number String Boolean undefined Null Object (Array)Function
基本類型:Number Boolean String undefined null
引用類型:Object (Array) Function
基本類型
的數(shù)據(jù)是存放在棧內(nèi)存
中的看蚜,而引用類型
的數(shù)據(jù)是存放在堆內(nèi)存
中的,引用類型會導(dǎo)致深淺拷貝的問題
基本類型
基本類型的變量是存放在棧內(nèi)存(Stack)里的
基本數(shù)據(jù)類型的值是按值訪問的
基本類型的值是不可變的
基本類型的比較是它們的值的比較
引用類型
引用類型的值是保存在堆內(nèi)存(Heap)中的對象(Object)
引用類型的值是按引用訪問的
引用類型的值是可變的
引用類型的比較是引用的比較
var p = 1;
var p1 = p;
基本類型的復(fù)制就是在棧內(nèi)存中開辟出了一個新的存儲區(qū)域用來存儲新的變量夯缺,
這個變量有它自己的值强岸,只不過和前面的值一樣峦树,所以如果其中一個的值改變渡冻,則不會影響到另一個戚扳。
var object1 = new Object();
var object2 = object1;
定義了一個對象其實是在棧內(nèi)存中存儲了一個指針,這個指針指向堆內(nèi)存中該對象的存儲地址族吻。
復(fù)制給另一個對象的過程其實是把該對象的地址復(fù)制給了另一個對象變量帽借,兩個指針都指向同一個對象,
所以若其中一個修改了超歌,則另一個也會改變砍艾。
String Boolean Number
這三種類型也叫做 基本包裝類型
有方法可以使用