天天看點

JS基礎問題

類型判斷

判斷JS中資料類型的幾種方法: typeof、instanceof、constructor、prototype、比較運算符等;

1、JS基本類型的文法比較

{} == {} 比較結果為false

[1] == [1] 比較結果為false

null == null 比較結果為true

undefined == null 比較結果為true

undefined === null 比較結果為false

注: == 表示值相等; === 表示值和類型都要一緻;

能力擴充:指針與引用的差別? 指針是一個實體,需要配置設定記憶體空間. 引用隻是變量的别名,不需要配置設定記憶體空間.

2、js中什麼類型是引用傳遞,什麼類型是值傳遞?如何将值類型的變量以引用的方式傳遞呢?

js中對象類型是引用傳遞,基礎資料類型是值傳遞. 可以通過将基礎類型包裝(boxing)可以以引用的方式傳遞. 引用類型包括:object、Array、RegExp、Date、Function等; 基本類型包括:undefined、null、string、number、boolean、symbol

如果要将值類型的變量以引用的方式傳遞,就需要包裝成引用類型,示例代碼:

const obj = {x: 1};

function foo(o) {

o.x = 3;

}

foo(obj);

console.log(obj.x);

執行結果obj.x值為3

3、 如何編寫一個json對象的拷貝函數?

根據深拷貝的啟發,不拷貝引用對象,拷貝一個字元串會開辟一個新的存儲位址,這樣就切斷了引用對象的指針聯系.示例代碼:

const test = {

a: “xxxx”,

b: “yyyy”,

c: [

{d: “div”, e: “element”},

{v: “video”}

]

};

const test1 = JSON.parse(JSON.stringify(test)); // 先序列化為字元串再反序列化為對象

console.log(test);

console.log(test1);

test.c[0].d=“dom”; // 改變test的c屬性的對象d屬性值

console.log(test); // test的d屬性值為dom

console.log(test1); // test1的d屬性值保持為div不變

4、 JS中不同類型以及不同環境下變量的記憶體都是何時釋放?

引用類型: 在沒有引用之後,通過V8的GC自動回收;

值類型:如果處于閉包的情況下,要等閉包沒有引用才會被GC回收; 非閉包的情況下等待v8的新生代(new space)切換的時候回收.

浏覽器環境:隻有當頁面關閉時,全局作用域下的變量才會被銷毀(保守GC)

V8引擎:GC政策采用分代GC,新生代使用Scavenge算法進行回收,舊分代使用标記和精簡GC.當堆超過閥值,啟動GC.

擴充1:下面代碼是否會使V8記憶體爆掉?

let arr = [];

while (true) {

arr.push(1);

}

執行最後的結果:記憶體爆掉,提示錯誤allocation failure GC in old space requested

擴充2:數組裡面push空元素結果是什麼?

let arr = [];

while (true) {

arr.push();

}

執行最後的結果:while(true)一直死循環下去,CPU資源耗盡.

擴充3:如果push的是Buffer情況結果會如何?

let arr = [];

while (true) {

arr.push(new Buffer(1000));

}

執行結果:最後系統的記憶體爆掉,因為Buffer申請的是堆外的記憶體空間

擴充4:閉包引發的記憶體洩露,問題示例代碼:

function out() {

const bigData = new Buffer(100);

inner = function() {

void bigData;

}

}

這個示例inner直接挂載在了root上,進而導緻記憶體洩露(因為bigData不會釋放)

進階擴充: 所有JS對象都是通過V8堆來配置設定的,存活時間較短的對象放在新生代,存活時間較長的對象放在老生代.記憶體回收政策上,新生代使用Scavenge算法進行回收,該算法實作中主要采用cheney算法.老生代使用标記-清除(Mark-Sweep)和标記-緊縮(Mark-Compact)來回收記憶體.