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