JavaScript變數提升的本質

來源:互聯網
上載者:User

JavaScript變數提升的本質
變數提升

先說三句總結性的話:

  • let 的「建立」過程被提升了,但是初始化沒有提升。
  • var 的「建立」和「初始化」都被提升了。
  • function 的「建立」「初始化」和「賦值」都被提升了。

所以,我們要注意,這三種變數提升,含義是不同的。

變數提升的規律

在進入一個執行內容後,先把 var 和 function 聲明的變數前置,再去順序執行代碼。

PS:範圍分為全域範圍和函數範圍,用var聲明的變數,只在自己所在的所用域有效。

我們舉例來看看下面的代碼。

代碼 1:

    console.log(fn);
    var fn = 1;

    functionfn() {
    }

    console.log(fn);

相當於:

    var fn = undefined;

    functionfn() {
    }

    console.log(fn);
    fn = 1;
    console.log(fn);

列印結果:

代碼 2:

    console.log(i);
    for (var i = 0; i < 3; i++) {
        console.log(i)
    }

相當於:

    var i = undefined;

    console.log(i);
    for (i = 0; i < 3; i++) {
        console.log(i);
    }

列印結果:

代碼 3:

    var a = 1;

    functionfn() {
        a = 2;
        console.log(a)
        var a = 3;
        console.log(a)
    }

    fn();
    console.log(a);

相當於:

    var a = undefined;

    functionfn() {
        var a

        a = 2
        console.log(a)
        a = 3
        console.log(a)
    };

    a = 1;
    fn();
    console.log(a);

列印結果:

聲明時的重名問題

假設a被聲明為變數,緊接著a又被聲明為函數,原則是:聲明會被覆蓋(先來後到,就近原則)。

PS:

  • 如果a已經有值,再用 var 聲明是無效的。
  • 如果a已經有值,緊接著又被賦值,則賦值會被覆蓋。

舉例1:

    var fn;  //fn被聲明為變數
    functionfn() {// fn被聲明為function,就近原則

    }

    console.log(fn); //列印結果:function fn(){}

舉例2:

    functionfn() {}  //fn被聲明為function,且此時fn已經被賦值,這個值就是function的對象

    var fn;  //fn已經在上一行被聲明且已經有值, 再 var 無效,並不會重設為 undefined

    console.log(fn)  //列印結果:function fn(){}既然再var無效,但是再function,是有效:

    functionfn() {}  //fn被聲明為function,且此時fn已經有值,這個值就是function的對象

    functionfn() {  //此時fn被重複賦值,會覆蓋上一行的值
        console.log('smyhvae');
    }
    console.log(fn)

列印結果:

函數範圍中的變數提升(兩點提醒)

提醒1:

在函數範圍也有聲明提前的特性:

  • 使用var關鍵字聲明的變數,是在函數範圍內有效,而且會在函數中所有的代碼執行之前被聲明
  • 函式宣告也會在函數中所有的代碼執行之前執行

因此,在函數中,沒有var聲明的變數都會成為全域變數,而且並不會提前聲明。

舉例1:

        var a = 1;

        functionfoo() {
            console.log(a);
            a = 2;    // 此處的a相當於window.a
        }

        foo();
        console.log(a);  //列印結果是2

上方代碼中,foo()的列印結果是1。如果去掉第一行代碼,列印結果是Uncaught ReferenceError: a is not defined

提醒2:定義形參就相當於在函數範圍中聲明了變數。

        function fun6(e) {
            console.log(e);
        }

        fun6();  //列印結果為 undefined
        fun6(123);//列印結果為123

其他題目

    var a = 1;
    if (a > 0) {
        console.log(a);
        var a = 2;
    }
    console.log(a);

列印結果:

1

2

上方代碼中,不存在塊級範圍的概念。if語句中用var定義的變數,仍然是全域變數。

順便延伸一下,用let定義的變數,是在塊級範圍內有效。

本文永久更新連結地址:https://www.bkjia.com/Linux/2018-03/151490.htm

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.