參考文檔:《深入理解javascript原型和閉包系列》
我們來看如下的代碼:
var num = 20;
function f1() {
console.log(num); // undefined
var num = 10;
console.log(num); // 10
}
f1();
==很奇怪為什么,第一個(gè)打印num的結(jié)果不是 20脐往?為什么第二個(gè)又是10?==
這里先引出一個(gè)基本知識(shí),==javascript中沒有塊級(jí)作用域的概念,只有全局作用域股耽,和函數(shù)作用域==根盒。
- 所謂作用域,通俗的可以理解為一個(gè)地盤物蝙,里面的函數(shù)炎滞、變量、常量都屬于這個(gè)作用域诬乞;
全局作用域是指函數(shù)册赛、變量、常量等對(duì)象的作用范圍在整個(gè)應(yīng)用程序中都是可用的丽惭。在全局作用域內(nèi)定義的對(duì)象被稱之為全局對(duì)象击奶。例如,在全局作用域內(nèi)定義的函數(shù)被稱為全局函數(shù)责掏,在全局作用域內(nèi)定義的變量稱之為全局變量。全局對(duì)象的生命期開始于應(yīng)用程序的運(yùn)行湃望,結(jié)束于應(yīng)用程序的退出换衬。
函數(shù)作用域則可以理解為函數(shù)大括號(hào)所囊括的地盤,里面的函數(shù)证芭、變量瞳浦、常量只在這個(gè)范圍內(nèi)可用。
我們回到開頭的例子废士,調(diào)用f1()時(shí)叫潦,進(jìn)行了哪些準(zhǔn)備工作;
- 變量官硝、函數(shù)表達(dá)式——變量聲明矗蕊,默認(rèn)賦值為undefined;
- this——賦值氢架;
- 函數(shù)聲明——賦值傻咖;
所以我們?cè)趫?zhí)行 f(); 其實(shí)做了相當(dāng)于如下的過程:
function f1() {
var num;
console.log(num); // undefined
num = 10;
console.log(num); // 10
}
先對(duì) num 進(jìn)行了聲明,但是沒有賦值岖研;
那么為什么 num 使用的不是 全局作用域里的 num = 20 呢卿操?
因?yàn)?==子作用域中的變量?jī)?yōu)先級(jí)比父親作用域的中優(yōu)先級(jí)高,當(dāng)子作用域中沒有這個(gè)變量是才會(huì)去父作用域中尋找==所以孙援,第一行輸出結(jié)果會(huì)是undefined害淤,第二行結(jié)果是10;
var a = 1
function fn1(){
function fn3(){
var a = 4
fn2()
}
var a = 2
return fn3
}
function fn2(){
console.log(a)
}
var fn = fn1()
fn() // 輸出 1
最后我們看看上面的例子拓售,結(jié)果會(huì)是1 窥摄,因?yàn)?fn2() 是屬于全局作用域的,自身作用域中沒有a 變量所以會(huì)去邻辉,全局作用域?qū)ふ摇?/p>