var a = 2; (function foo() { var a = 3; console.log(a);//3 })();//IIFE console.log(a);//2
輸出:3 2
foo綁定在函數表達式自身的函數中而不是所在做用域,使值爲3的變量a只能在{..}內被訪問。 且foo變量名不會污染外部做用域。函數
var a=2; (function IIFE(global) {//參數名爲global var a=3; console.log(a);//3 console.log(global.a);//2 })(window);//將window對象的引用傳遞進去 console.log(a);//2
輸出:3 2 2
當即執行函數表達式的傳參版本。code
//倒置代碼運行順序 var a=2; (function iife(def) { def(window); })(function def(global) { var a=3; console.log(a);//3 console.log(global.a);//2 }); console.log(a);
輸出:3 2 2
同上。對象
try { undefined();//執行一個非法操做來製造異常 } catch(err) { console.log(err);//TypeError: undefined is not a function } console.log(err);//Uncaught ReferenceError: err is not defined
說明:err僅存在catch分句內部。ip
var foo=true; if(foo) { let bar=foo*2; var b = foo*3; console.log(b); console.log(bar); } console.log(b); console.log(bar);
輸出:
3
2
3
Uncaught ReferenceError: bar is not defined
let關鍵字將變量綁定到所在做用域,因此在全局做用域找不到變量bar。作用域
for(var i=0; i<10; ++i) { console.log(i); } console.log(i);
輸出:1 2 3 4 5 6 7 8 9 10io
for(let i=0; i<10; ++i) { console.log(i); } console.log(i);
輸出:1 2 3 4 5 6 7 8 9 Uncaught ReferenceError: i is not definedconsole
var foo=true; if(foo) { var a=2; const b=3; console.log(a); console.log(b); a=3; b=4; } console.log(a); console.log(b);
輸出:2 3 Uncaught TypeError: Assignment to constant variable.
在爲b賦值時直接報錯,由於const的值是固定的,試圖修改會引發錯誤。編譯
若是將b=4;
註釋掉,則
輸出:2 3 3 Uncaught ReferenceError: b is not defined
const與let同樣,將變量綁定到所在做用域。function
總結:變量和函數聲明被提高到最上面,函數表達式不會被提高。變量
a=2; var a; console.log(a); console.log(b); var b=2; /*以上代碼至關於 var a; var b; a=2; console.log(a); console.log(b); b=2;*/
輸出:2 undefinedvar a;
定義聲明在 編譯 階段進行a=2;
賦值聲明在原地等待 執行 階段
變量a的定義聲明var a;
被提高到最上面,即 a=2
以前,因此沒有報錯undefined.
foo();//1 var foo; function foo() { console.log(1); } foo=function() { console.log(2); } /*以上代碼至關於 function foo() { console.log(1); } foo(); foo=function() { console.log(2); }
輸出:1
函數foo的聲明var foo;
被提高到最上面。
注:函數首先被提高,而後是變量。且,函數聲明可覆蓋。
代碼引用自《你不知道的JavaScript》系列,部分有更改。