首先先看一段代碼:
var num = 12;
var obj = {
name: 'derrick',
age: 20
};
function fn() {
console.log('勿忘初心,方得始終。');
}
console.log(fn); // 把整個(gè)函數(shù)的定義部分(函數(shù)本身)在控制臺(tái)輸出
console.log(fn()); // 把當(dāng)前函數(shù)執(zhí)行的返回結(jié)果(return后面寫的是啥,返回值就是啥,沒有return,默認(rèn)返回值是undefined)輸出
其簡略的過程圖可如下表示
分析圖.png
當(dāng)瀏覽器加載HTML頁面的時(shí)候,首先會(huì)提供一個(gè)供全局JavaScript代碼執(zhí)行的環(huán)境,稱之為全局作用域(global/ window)。
預(yù)解釋(變量提升):在當(dāng)前的作用域中,JavaScript代碼執(zhí)行之前,瀏覽器首先會(huì)默認(rèn)的把所有帶var和function的進(jìn)行提前聲明或者定義。
1) 理解聲明和定義:
對于var num = 12;
:
聲明(declaration):var num;
-> 告訴瀏覽器在全局作用域中有一個(gè)num的變量了,如果一個(gè)變量只是申明了,但是沒有賦值,默認(rèn)值是undefined。
**定義(definition): **num = 12;
-> 給變量進(jìn)行賦值。
2) 對于帶var關(guān)鍵字和帶function關(guān)鍵字的,在預(yù)解釋的時(shí)候操作還是不一樣的
var: 在預(yù)解釋的時(shí)候只是提前的聲明。
**function: **在預(yù)解釋的時(shí)候,提前的聲明和定義都完成了。
- 預(yù)解釋只發(fā)生在當(dāng)前的作用域當(dāng)中,例如:開始只對window下的預(yù)解釋,只有函數(shù)執(zhí)行的時(shí)候,才會(huì)對函數(shù)中的部分進(jìn)行預(yù)解釋。
console.log(num); // undefined
var num = 12;
var obj = {
name: 'derrick',
age: 20
};
console.log(num); // 12
fn(100, 200); // 可以在這里執(zhí)行,因?yàn)轭A(yù)解釋的時(shí)候,函數(shù)的聲明和定義都已經(jīng)完成了
function fn(num1, num2) {
var total = num1 + num2;
console.log(total);
}
分析圖.png
JavaScript中內(nèi)存的分類
棧內(nèi)存: 用來提供一個(gè)供JavaScript代碼執(zhí)行的環(huán)境 -> 作用域(全局作用域,私有作用域)。
堆內(nèi)存: 用來存儲(chǔ)引用數(shù)據(jù)類型的值 -> 對象存儲(chǔ)的是屬性名和屬性值, 函數(shù)存儲(chǔ)的是代碼字符串。