javascript中變量提高的理解

網上找了兩個經典的例子javascript

var foo = 1;
function bar() {
    if (!foo) {
        var foo = 10;
    }
    alert(foo);
}
bar();  // 10
var a = 1;
function b() {
    a = 10;
    return;
    function a() {}
}
b();
alert(a);// 1

在JavaScript中,函數、變量的聲明都會被提高(hoisting)到該函數或變量所在的scope的頂部。即——JavaScript的變量提高。html

javascript中一個名字(name)以四種方式進入做用域(scope),其優先級順序以下:java

  • 語言內置:全部的做用域中都有 this 和 arguments 關鍵字;
  • 形式參數:函數的參數在函數做用域中都是有效的;
  • 函數聲明:形如function foo() {};
  • 變量聲明:形如var bar;

名字聲明的優先級如上所示。也就是說若是一個變量的名字與函數的名字相同,那麼函數的名字會覆蓋變量的名字,不管其在代碼中的順序如何。但名字的初始化倒是按其在代碼中書寫的順序進行的,不受以上優先級的影響。git

(function(){
    var foo;
    console.log(typeof foo);  //function
     
    function foo(){}
 
    foo = "foo";
    console.log(typeof foo);  //string
    
    var foo;
})();
function test() {
    foo();             // TypeError "foo is not a function"
    bar();             // "this will run!"
    var foo = function () { // function expression assigned to local variable 'foo'
        alert("this won't run!");
    }
    function bar() {   // function declaration, given the name 'bar'
        alert("this will run!");
    }
}
test();

變量的提高(Hoisting)只是其定義提高,而變量的賦值並不會提高
再來看一個例子,下面兩段代碼實際上是等價的:github

function foo() {
    if (false) {
        var x = 1;
    }
    return;
    var y = 1;
}
function foo() {
    var x, y;
    if (false) {
        x = 1;
    }
    return;
    y = 1;
}

建立一個函數的方法有兩種:
一種是經過函數聲明function foo(){}
另外一種是經過定義一個變量var foo = function(){}express

function test() {
    foo(); // TypeError "foo is not a function"
    bar(); // "this will run!"
    var foo = function () { // function expression assigned to local variable 'foo'
        alert("this won't run!");
    }
    function bar() { // function declaration, given the name 'bar'
        alert("this will run!");
    }
}
test();

var foo首先會上升到函數體頂部,然而此時的fooundefined,因此執行報錯。而對於函數bar, 函數自己也是一種變量,因此也存在變量上升的現象,可是它是上升了整個函數,因此bar()纔可以順利執行。segmentfault

本文參考自:
http://www.cnblogs.com/damonlan/archive/2012/07/01/2553425.html
http://www.javashuo.com/article/p-mlexwjqf-cp.html
https://segmentfault.com/a/1190000005794611函數


做者博客:pspgbhuthis

做者GitHub:https://github.com/pspgbhucode

歡迎轉載,但請註明出處,謝謝!

相關文章
相關標籤/搜索