1. 程式人生 > >JavaScript 變量聲明提升

JavaScript 變量聲明提升

賦值 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
  • 第二步:代碼自上而下、自左向右執行計算:
  1. 對全局變量foo進行賦值foo={n:1};註意:此值為對象,屬於引用類型;
  2. 匿名函數傳入參數foo={n:1}自執行;
  3. console.log(foo);打出數字1;
  4. 由於存在foo局部變量,那麽對foo變量進行賦值foo={n:3},同時更改了引用類型的參數值,全局foo變量被重新賦值foo={n:3};
  5. 對局部變量foo進行重新賦值foo={n:2};
  6. console.log(foo);打出數字2;
  7. 全局變量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 變量聲明提升