{ console.log(num);//num is not defined let num = 123;//從定義開(kāi)始至所在的花括號(hào)結(jié)束的范圍內(nèi)生效 console.log(num);}console.log(num);(2)詞法作用域
在 js 中(不考慮 ES6 特性)是沒(méi)有塊級(jí)作用域的,只有詞法作用域詞法作用域:與代碼的運(yùn)行無(wú)關(guān),只與代碼的定義書寫內(nèi)容有關(guān)。黃金法則:只有函數(shù)可以限定作用域,變量聲明會(huì)提升,訪問(wèn)先在當(dāng)前找,沒(méi)有父級(jí)作用域來(lái)查。可以利用代碼的書寫繪制出代碼的作用域關(guān)系。練習(xí):if(!('a' in window)){ var a = 123;}console.log(a);var a = 123;function b(a){ console.log(a); function a(){ console.log('a'); }}b(a);in 運(yùn)算符語(yǔ)法:'字符串' in 對(duì)象 -> boolean含義:該對(duì)象中是否存在屬性名字為字符串的形式,如果存在返回 true例如:var p = {name: xxx};'name' in p; //true'age' in p; //false繪制作用域關(guān)系圖:① 在全局范圍內(nèi)聲明的所有變量,都是在該范圍內(nèi)可以被使用的,而且沒(méi)有前后順序之分② 如果有函數(shù),那么函數(shù)內(nèi)部是獨(dú)立于外界的一個(gè)完整的作用域范圍function foo(){ //函數(shù)內(nèi)部也要預(yù)解析,聲明提升 console.log(num); var num = 10; console.log(num);}foo(); //先打印undefined,后打印10③ 在函數(shù)內(nèi)部如果沒(méi)有找到對(duì)應(yīng)的變量,會(huì)到函數(shù)外面查找;如果函數(shù)內(nèi)部和函數(shù)外部同時(shí)有變量,優(yōu)先使用函數(shù)內(nèi)部的。先后打印:456、123、123
結(jié)果:報(bào)錯(cuò),num is not defined,num向上一層找到了變量聲明并使用,而此聲明是在函數(shù)體內(nèi)的,不在全局范圍,故num不是全局變量,只是函數(shù)foo1內(nèi)部的變量
結(jié)果:打印456,num向上所有層找都沒(méi)有找到變量聲明,故num成為了全局變量
2. 作用域鏈
在分析代碼的時(shí)候,多個(gè)作用域中含有哪些數(shù)據(jù),不容易記住根據(jù)變量訪問(wèn)的搜索規(guī)則(當(dāng)前有就用,沒(méi)有就上一級(jí)搜索)繪制作用域鏈規(guī)則:① 把全局作用域看作0級(jí)作用域,繪制一條直線② 凡是看到函數(shù),就延伸出一條鏈,記為 n+1 級(jí)鏈③ 進(jìn)入函數(shù)內(nèi),重復(fù)上述操作注意:在繪制鏈的時(shí)候,不要給任何變量賦值,將圖繪制完成以后,再一句一句分析代碼,將數(shù)據(jù)添加上去例:3. 變量的訪問(wèn)規(guī)則
在訪問(wèn)一個(gè)變量的時(shí)候,首先在當(dāng)前作用域中查找,如果找到則使用,并停止查找,如果沒(méi)找到則在上一級(jí)作用域中查找(上一級(jí)鏈),如此往復(fù),一定會(huì)找到全局作用域(0級(jí)鏈),如果還沒(méi)有數(shù)據(jù),則報(bào)錯(cuò)(is not defined),如果是設(shè)置數(shù)據(jù),則會(huì)在全局作用域中增加一個(gè)屬性(此處嚴(yán)格模式會(huì)報(bào)錯(cuò))。4. eval 函數(shù)
將字符串作為代碼執(zhí)行語(yǔ)法:eval( '語(yǔ)句' )一般網(wǎng)站不需要考慮安全性的時(shí)候,可以這么使用,但是現(xiàn)在已經(jīng)不建議使用了。推薦使用 Function 實(shí)現(xiàn)類似的功能。注意:在嚴(yán)格模式下,eval 可以限定作用域。
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注