JavaScript 變量聲明提升
阿新 • • 發佈:2017-08-05
賦值 logs 類型 type spa peer 表達式 ror 數值
(function() { var x=foo(); var foo=function foo() { return ‘foobar‘ }; return x; })();
這段代碼運行後報錯:Uncaught TypeError: foo is not a function
原因在於變量foo的聲明提升,後面的賦值,函數表達式不會提升,因此當代碼運行到 var x=foo(); 時,
foo()是未定義的。
可以把 var x=foo(); 放到 變量 foo 後再執行:
(function() { var foo=function foo() { return ‘foobar‘ }; var x=foo(); return x; })();
函數聲明整個提升到作用域頂部,比如這樣寫:
(function() { var x=foo(); function foo() { return ‘foobar‘ } return x; })();
再看一個例子:
var foo = {n:1}; (function (foo) { //註意這裏,傳進參數 foo console.log(foo.n); foo.n=3; //全局變量重新賦值, var foo={n:2}; //局部變量foo進行重新賦值 console.log(foo.n); })(foo); console.log(foo.n);//全局變量已經是 n:3
- 第一步:進行預編譯,var全局變量foo、匿名函數 function、var局部變量foo
- 第二步:代碼自上而下、自左向右執行計算:
- 對全局變量foo進行賦值foo={n:1};註意:此值為對象,屬於引用類型;
- 匿名函數傳入參數foo={n:1}自執行;
- console.log(foo);打出數字1;
- 由於存在foo局部變量,那麽對foo變量進行賦值foo={n:3},同時更改了引用類型的參數值,全局foo變量被重新賦值foo={n:3};
- 對局部變量foo進行重新賦值foo={n:2};
- console.log(foo);打出數字2;
- 全局變量foo={n:3},因此,console.log(foo);打出數字3;
關於var x1=foo(); 和 var x2=foo; 有沒括號的區別
函數是一種叫做function引用類型的實例,因此函數是一個對象。對象是保存在內存中的,函數名則是指向這個對象的指針。
函數可以作為參數傳入別的函數,也可以作為一個函數的返回值,也可以被重新賦值。
簡單來說,x1是函數foo()的返回值,x2是函數foo()本身。
(function() { var foo=function foo() { return ‘foobar‘ }; var x=foo; return x; })(); //function foo() { return ‘foobar‘ }
JavaScript 變量聲明提升