1. 什么是堆棧
在計算機(jī)領(lǐng)域中娘汞,堆棧是兩種數(shù)據(jù)結(jié)構(gòu),它們只能在一端(稱為棧頂(top))對數(shù)據(jù)項進(jìn)行插入和刪除夕玩,因而按照后進(jìn)先出的原理運作你弦。
- 棧 stack:由編譯器自動分配釋放,存放函數(shù)的參數(shù)值燎孟,局部變量的值等禽作。其操作方式類似于數(shù)據(jù)結(jié)構(gòu)中的棧。
- 堆 heap:一般由程序員分配釋放缤弦, 若程序員不釋放领迈,程序結(jié)束時可能由OS回收。注意它與數(shù)據(jù)結(jié)構(gòu)中的堆是兩回事碍沐,分配方式倒是類似于鏈表。
2. JavaScript中的基本類型和引用類型與堆棧的聯(lián)系
- 基本類型:Undefined衷蜓、Null累提、Boolean、Number 和 String磁浇,這5中基本數(shù)據(jù)類型可以直接訪問斋陪,他們是按照值進(jìn)行分配的,存放在棧(stack)內(nèi)存中的簡單數(shù)據(jù)段,數(shù)據(jù)大小確定无虚,內(nèi)存空間大小可以分配缔赠。
- 引用類型:即存放在堆(heap)內(nèi)存中的對象,變量實際保存的是一個指針友题,這個指針指向另一個位置嗤堰。
內(nèi)存
棧 stack 內(nèi)存 | 堆 heap 內(nèi)存 |
---|---|
1 | |
"hello" | |
true | |
null | |
undefined | |
object1 | {name: 'tom', age: 23} |
array1 | [1,2,3] |
varible | 23 |
varible = object1.age 是引用,所以在堆中保存的是指針度宦,在棧中保存的引用數(shù)據(jù)
- 最新的基本類型和引用類型踢匣,以及之間的區(qū)別。
基本數(shù)據(jù)類型:按值訪問戈抄,可操作保存在變量中的實際的值离唬。基本類型值指的是簡單的數(shù)據(jù)段划鸽。
基本數(shù)據(jù)類型有這六種:undefined输莺、null、string裸诽、number模闲、boolean、symbol(es6)崭捍。
引用類型:當(dāng)復(fù)制保存著對象的某個變量時尸折,操作的是對象的引用,但在為對象添加屬性時殷蛇,操作的是實際的對象实夹。引用類型值指那些可能為多個值構(gòu)成的對象。
引用類型有這幾種:Object粒梦、Array亮航、RegExp、Date匀们、Function缴淋、特殊的基本包裝類型(String、Number泄朴、Boolean)以及單體內(nèi)置對象(Global重抖、Math)。
3. 什么是淺拷貝祖灰,深拷貝
- 基本類型:Undefined钟沛、Null、Boolean局扶、Number 和 String恨统,這5中基本數(shù)據(jù)類型的拷貝叁扫,是直接在棧(stack)中增加新數(shù)據(jù),拷貝前后互不相干畜埋,所以不存在淺拷貝和深拷貝
- 引用類型, 淺拷貝下莫绣,拷貝引用類型的屬性時,是拷貝引用的指針悠鞍,所以修改內(nèi)容會影響原始對象对室。深拷貝下,拷貝引用類型的屬性時狞玛,是拷貝內(nèi)容软驰,所以修改不影響原始對象。
4. 手寫淺拷貝心肪,深拷貝
淺拷貝一锭亏,for in
function copy(obj){
var newObj = {};
for(var key in obj){
newObj[key] = obj[key];
}
return newObj;
}
淺拷貝二, Object.keys
function copy2(obj){
var newObj = {};
Object.keys(obj).forEach(key=>{
newObj[key] = obj[key]
})
return newObj;
}
深拷貝一,最簡單硬鞍,但只支持符合JSON格式的
function deepCopy(obj) {
return JSON.parse(JSON.stringify(obj));
}
深拷貝二慧瘤,(推薦)基本類型直接賦值,對象分三種情況固该,null, array锅减,object,函數(shù)方法直接賦值
function deepCopy(obj){
var o;
switch(typeof obj){
case 'undefined': break;
case 'string' : o = obj + '';break;
case 'number' : o = obj - 0;break;
case 'boolean' : o = obj;break;
case 'object' :
if(obj === null){
o = null;
}else{
if(obj instanceof Array){
o = [];
for(var i = 0, len = obj.length; i < len; i++){
o.push(deepCopy(obj[i]));
}
}else{
o = {};
for(var k in obj){
o[k] = deepCopy(obj[k]);
}
}
}
break;
default:
o = obj;break;
}
return o;
}
深拷貝三伐坏,缺點怔匣,只支持拷貝對象
function deepCopy(obj, clone) {
clone = clone || {}
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
if (typeof obj[key] === 'object') {
clone[key] = Array.isArray(obj[key]) ? [] : {}
deepCopy(obj[key], clone[key])
} else {
clone[key] = obj[key]
}
}
}
return clone
}