變量提高的意思是在一個變量做用域裏定義的變量的聲明會被提高到做用域的頂部,這是變量只會被聲明,不會被初始化複製,而是undefined。javascript
代碼以下:html
function scopefunc() { console.log(variable1); /* console.log(variable2);*/ var variable1 = "I'm variable1"; console.log(variable1); }; window.onload = function () { scopefunc(); }
運行結果:java
undefinednode
I'm variable1函數
被註釋的那句代碼會報錯,證實沒被定義的變量不是undefined而是直接報錯。this
針對變量的這個特性,在編寫javascript代碼時,應當遵循這樣的風格:spa
在一個做用域的頂部使用一個 var 且定義全部的變量,可初始化或不初始化命令行
以下:code
1 function scropefunc() { 2 var variable1 = "I'm variable1", 3 variable2,func1; 4 console.log(variable1); 5 func1 = function () { 6 variable2 = "I'm variable2"; 7 console.log(variable2); 8 }; 9 }
ES6中使用的let 聲明的變量不會發生變量提高,同時做用域是塊做用域,表現就是當前花括號內。htm
函數聲明:
(function() { log("first log"); function log(arg) { console.log(arg); } log("second log"); })();
函數聲明也會被提到做用域的頂部,因此在聲明以前使用函數也是能夠的,好比上面的log函數。
ES5中函數聲明不能在塊中,但ES6中能夠在塊中聲明函數,相似於使用了let因此不能提早使用,在具體使用時仍是很容易使人迷惑的,因此避免在塊中聲明函數。
在上面一段代碼中,func1函數裏訪問了variable2這個變量,可是這個變量只是在func1的外面的scopefunc函數內定義的,沒有被func1所定義,那麼func1是怎麼找到的呢?
先介紹執行環境的概念,函數被調用時會產生一個新的執行環境,在JavaScipt引擎中,執行環境對象實現了執行環境這個概念。執行環境是能夠嵌套的,而且內層的執行環境能夠訪問外層的執行環境,但外層的不能訪問內層的執行環境。就像是一條鏈子,JavaScript在訪問變量時,從當前執行環境開始查找,若是沒有找到,向上一級執行環境中查找,直到頂級的執行環境(html中是window對象,nodejs是global),
當即調用函數表達式的全稱是 Immediately Invoked Function Expression
這是一個js函數,在定義時就會執行,一般會用來防止污染全局變量,在模塊模式中常常會用到
代碼示例以下:
(function() { var private_Var = 7; console.log("this is inner IIFE"); })();
將這段代碼靠到nodejs的命令行,回車就會輸出this is inner IIFE,而且訪問private_Var會出錯。