一乾蛤、數(shù)據(jù)類型存儲
基本類型(保存在棧內(nèi)存中)
引用類型(保存在堆內(nèi)存中,引用數(shù)據(jù)類型的變量是一個指向堆內(nèi)存中中實際對象的引用,存在棧中)
二力喷、淺拷貝
淺拷貝,指的是創(chuàng)建新的數(shù)據(jù)演训,這個數(shù)據(jù)有著原始數(shù)據(jù)屬性值的一份精確拷貝如果屬性是基本類型弟孟,拷貝的就是基本類型的值。如果屬性是引用類型样悟,拷貝的就是內(nèi)存地址即淺拷貝是拷貝一層拂募,深層次的引用類型則共享內(nèi)存地址下面簡單實現(xiàn)一個淺拷貝
functionshallowClone(obj){
????const?newObj?=?{};
????for(let?prop?in?obj)?{
????????if(obj.hasOwnProperty(prop)){
????????????newObj[prop]?=?obj[prop];
????????}
????}
????return?newObj;
}
在JavaScript中,存在淺拷貝的現(xiàn)象有:
Object.assign
Array.prototype.slice(),?Array.prototype.concat()
使用拓展運算符實現(xiàn)的復(fù)制
Object.assign
varobj?=?{
age:18,
nature:?['smart','good'],
names:?{
name1:'fx',
name2:'xka'
},
love:function(){
console.log('fx?is?a?great?girl')
}
}
var newObj?=Object.assign({},?fxObj);
slice()
constfxArr?=?["One","Two","Three"]
constfxArrs?=?fxArr.slice(0)
fxArrs[1]?="love";
console.log(fxArr)//?["One",?"Two",?"Three"]
console.log(fxArrs)//?["One",?"love",?"Three"]
concat()
constfxArr?=?["One","Two","Three"]
constfxArrs?=?fxArr.concat()
fxArrs[1]?="love";
console.log(fxArr)//?["One",?"Two",?"Three"]
console.log(fxArrs)//?["One",?"love",?"Three"]
拓展運算符
constfxArr?=?["One","Two","Three"]
constfxArrs?=?[...fxArr]
fxArrs[1]?="love";
console.log(fxArr)//?["One",?"Two",?"Three"]
console.log(fxArrs)//?["One",?"love",?"Three"]
三窟她、深拷貝
深拷貝開辟一個新的棧陈症,兩個對象屬性完成相同,但是對應(yīng)兩個不同的地址震糖,修改一個對象的屬性录肯,不會改變另一個對象的屬性
常見的深拷貝方式有:
_.cloneDeep()
jQuery.extend()
JSON.stringify()
手寫循環(huán)遞歸
_.cloneDeep()
const_?=require('lodash');
constobj1?=?{
a:1,
b:?{f:?{g:1}?},
c:?[1,2,3]
};
constobj2?=?_.cloneDeep(obj1);
console.log(obj1.b.f?===?obj2.b.f);//?false
jQuery.extend()
const$?=require('jquery');
constobj1?=?{
a:1,
b:?{f:?{g:1}?},
c:?[1,2,3]
};
constobj2?=?$.extend(true,?{},?obj1);
console.log(obj1.b.f?===?obj2.b.f);//?false
JSON.stringify()
constobj2=JSON.parse(JSON.stringify(obj1));
但是這種方式存在弊端,會忽略undefined吊说、symbol和函數(shù)
constobj?=?{
name:'A',
name1:undefined,
name3:function(){},
name4:Symbol('A')
}
constobj2?=JSON.parse(JSON.stringify(obj));
console.log(obj2);//?{name:?"A"}
循環(huán)遞歸
functiondeepClone(obj,?hash?=?new?WeakMap()){
if(obj?===null)returnobj;//?如果是null或者undefined我就不進行拷貝操作
if(objinstanceofDate)returnnewDate(obj);
if(objinstanceofRegExp)returnnewRegExp(obj);
//?可能是對象或者普通的值??如果是函數(shù)的話是不需要深拷貝
if(typeofobj?!=="object")returnobj;
//?是對象的話就要進行深拷貝
if(hash.get(obj))returnhash.get(obj);
letcloneObj?=newobj.constructor();
//?找到的是所屬類原型上的constructor,而原型上的?constructor指向的是當(dāng)前類本身
hash.set(obj,?cloneObj);
for(letkeyinobj)?{
if(obj.hasOwnProperty(key))?{
//?實現(xiàn)一個遞歸拷貝
cloneObj[key]?=?deepClone(obj[key],?hash);
}
}
returncloneObj;
}