一、深入了解JavaScript執(zhí)行過程(從具體代碼的角度)
1虎韵、為什么我們在JavaScript代碼中易稠,能直接使用window、setTimeout包蓝、console驶社、math等等對象或函數(shù)呢企量?
- 【前提】JavaScript執(zhí)行所以代碼都是有執(zhí)行上下文環(huán)境的
- 在全局上下文創(chuàng)建的時候,會創(chuàng)建一個GlobalObject(GO)亡电,里面就會注入我們經(jīng)常見到的window届巩、math、console等等函數(shù)或?qū)ο?/li>
// 示例代碼
var name = "why"
var num1 = 20
var num2 = 30
var result = num1 + num2
// GO的偽代碼(創(chuàng)建時間點份乒,也就是全局執(zhí)行上下文創(chuàng)建的時候)
var globalObject {
String:"類",
Date:"類",
setTimeout:"函數(shù)",
name: undefined,
num1:undefined,
num2:undefined,
result:undefined
}
image.png
2恕汇、觀察下面的代碼,先 console.log(num1)
后 var num1 = 20
或辖,結(jié)果輸出是什么瘾英?為什么?
var name = "why";
console.log(num1);
var num1 = 20;
var num2 = 30;
var result = num1 + num2;
- 【輸出】undefined
- 【原因】①在創(chuàng)建上下文時候颂暇,GO會將var的對象放到了window屬性中缺谴,只是值是
undefined
②在執(zhí)行上下文的時候,執(zhí)行到var num1 = 20
才會被賦值耳鸯。
3湿蛔、下面代碼,先調(diào)用函數(shù)片拍,再定義函數(shù)煌集,為什么不會報錯?
var name = "why";
foo();
function foo() {
console.log("foo");
}
- 【原因】①在創(chuàng)建上下文時候捌省,GO會將函數(shù)放到了window屬性中苫纤,值是函數(shù)地址
foo: 0xa00
②在執(zhí)行上下文的時候,執(zhí)行到foo();
時纲缓,拿到函數(shù)地址卷拘,進行執(zhí)行
4、思考下面代碼的輸出祝高?為什么會這樣栗弟?
var message = "Hello Global";
function foo() {
console.log(message);
}
function bar() {
var message = "Hello Bar";
foo();
}
bar();
- 【輸出】
Hello Global
- 因為函數(shù)的【parent scope父級作用域】在函數(shù)定義的時候確定的,與函數(shù)的調(diào)用無關
image.png
5工闺、一些經(jīng)典題目練習乍赫,對上面的知識的鞏固
image.png
- 【注意】對于
b=100
這種代碼,其實是未定義b陆蟆,直接使用b雷厂,js做了特殊處理,把b當成全局屬性了叠殷。不推薦這樣寫代碼改鲫,屬于特例。
二、內(nèi)存管理
1像棘、說說你對編程語言的內(nèi)存管理的認識稽亏?現(xiàn)在高級語言對內(nèi)存管理主要有哪兩大方式?
- 【不管什么樣的編程語言缕题,在代碼的執(zhí)行過程中都是需要給它分配內(nèi)存的】
- 【不同的是某些編程語言需要我們自己手動的管理內(nèi)存截歉,某些編程語言會可以自動幫助我們管理內(nèi)存】
image.png
2、JavaScript對基本數(shù)據(jù)類型和復雜數(shù)據(jù)類型避除,分配內(nèi)存的方式有什么不同怎披?
image.png
-【備注】好像沒法打印出JavaScript中變量的內(nèi)存地址。
3瓶摆、為什么要釋放內(nèi)存凉逛?什么是垃圾回收機制?
- 【因為內(nèi)存的大小是有限的群井,所以當內(nèi)存不再需要的時候状飞,我們需要對其進行釋放】
image.png
4、常見的兩種GC算法是哪兩種书斜?
- 【引用計數(shù)器方案】:這個算法有一個很大的弊端就是可能會產(chǎn)生循環(huán)引用問題
- 【標記清除方案】:這個算法可以很好地解決循環(huán)引用的問題
image.png
image.png