成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

JavaScript——作用域、變量聲明提升、局部變量混談

luffyZh / 3062人閱讀

摘要:主要聊聊局部變量作用域變量聲明提升作用域中有以下兩種作用域全局作用域函數(shù)作用域全局作用域是函數(shù)之外最外層代碼的作用域。相對于全局作用域,可以稱之為局部作用域相對于全局變量可以將其成為局部變量。然而,這里的是在下一行進行聲明的局部變量。

主要聊聊局部變量、作用域、變量聲明提升 作用域

JavaScript中有以下兩種作用域

全局作用域

函數(shù)作用域

全局作用域是函數(shù)之外(最外層代碼)的作用域。在函數(shù)之外進行聲明的名稱屬于全局作用域。這些名稱就是所謂的全局變量以及全局函數(shù)。
而在函數(shù)內(nèi)部進行聲明的名稱擁有的是函數(shù)作用域,它們僅在函數(shù)內(nèi)部才有效。相對于全局作用域,可以稱之為局部作用域;相對于全局變量可以將其成為局部變量。作為函數(shù)形參的參數(shù)變量也屬于函數(shù)作用域。

        var x = 1;
        function f() {
            alert("x:"+x);
            var x = 2;
            alert("x:"+x);
        };
        f();            // undefined | 2

可能會認為函數(shù)f內(nèi)第一個alert顯示的是全局變量x。然而,這里的x是在下一行進行聲明的局部變量x。這是因為,局部變量x的作用域是整個函數(shù)f內(nèi)部。由于此時還沒有對其進行賦值,因此變量x的值為undefined。

等價于:

        function f() {
            var x;
            alert("x:"+x);
            x = 2;
            alert("x:"+x);
        };
        f();

所以,未避免發(fā)生錯誤,一般建議在函數(shù)開始處對所有的局部變量進行聲明。

塊級作用域
        var x = 1;
        {var x = 2;alert(x);}    // 2
        
        alert(x);                 // 2

如果認為塊級作用域存在,則會認為第二個alert的結(jié)果會是1,可是結(jié)果是2
看似是在代碼塊中重新聲明了塊級作用域中的變量x,但實際上,它只是將全局變量賦值為了2。等價于:

        var x = 1;            
        {x:2;alert(x);}        // 2
        x = 2;
        alert(x);            // 2

在函數(shù)作用域中也存在對塊級作用域的誤解。在for語句中對循環(huán)變量進行聲明是一種習慣做法,不過該循環(huán)變量的作用域并不局限與for語句內(nèi)。下面的代碼中,其實是對局部變量i進行了循環(huán)使用。

        function f() {
            var i = 1;
            for (var i=1;i<10;i++) {
                // 省略
            }
            // 此時變量i的值為10
        };
let與塊級作用域

ECMAScript5中沒有塊級作用域,但是JavaScript自帶有let這一增強功能。感興趣的可以試一試

嵌套函數(shù)與作用域

在JavaScript中可以對函數(shù)進行嵌套聲明。就是說,在一個函數(shù)中聲明另一個函數(shù)。這時,內(nèi)部函數(shù)可以訪問外部函數(shù)的作用域。從形式上來說,名稱的查找是由內(nèi)向外的。在最后會查找全局作用域中的名稱。

        function f1() {
            var x = 1;            // 函數(shù)f1的局部變量
            
            // 嵌套函數(shù)聲明
            function f2() {
                var y = 2;        // 函數(shù)f2的局部變量
                alert(x);        // 將向上一層訪問f1的局部變量
                alert(y);            
            };
            function f3() {
                alert(y);        // 如果不存在全部變量y,將返回ReferenceError
            }
            // 調(diào)用
            f2();
            f3();
        };
        f1();
變量隱藏

指的是,通過作用域較小的變量(或者函數(shù)),來隱藏作用域較大的同名變量(或函數(shù))。這種情況常常會在無意中發(fā)生,從而造成錯誤。如:

        var n = 1;            
        function f() {
            var n = 2;
            alert(n);
        };
        f();
        // 這里就是局部變量隱藏了全局變量
接下來做題做題:
var a = 10;
function test(){
     a = 100;
     console.log(a);
     console.log(this.a);
     var a;
     console.log(a);
 }
 test();

在JS腳本執(zhí)行前,JS解釋器會對整個腳本聲明部分做解析,從而確定變量作用域,這里的var a會因為變量聲明提升,會被首先執(zhí)行,然后才是賦值(賦值的時間嚴格按照程序執(zhí)行順序來進行),第一個console輸出100;

第二個console我們發(fā)現(xiàn)了this引用,看見this引用就必須想this被誰調(diào)用,test函數(shù)是全局函數(shù),當然是全局對象調(diào)用,所以就等于window.a,而全局變量已經(jīng)在開頭聲明過了var a=10,輸出10;

最后一個console,這個a是誰?因為處于函數(shù)作用域內(nèi),查找由內(nèi)至外,局部變量已經(jīng)存在,當然輸出局部變量,結(jié)果為100;

100/10/100

 var a = 100;
 function test(){
     console.log(a);
     var a = 10;
     console.log(a);
 }
 test()

分析函數(shù),變量聲明提前,所以var a = 10會在函數(shù)執(zhí)行前先進行聲明,但是未被賦值!賦值的時間按照源碼的順序照常執(zhí)行。所以第一個consoleundefined
然后進行賦值a = 10,之后再console,結(jié)果10。

undefined/10
 var a = 100;
 function test(){
     console.log(a);
     a = 10;
     console.log(a);
 }
 test();
 console.log(a);

這里test函數(shù)內(nèi)部有聲明var嗎?沒有,所以這里的a其實是全局變量中的a,則第一個console結(jié)果為100;
之后賦值覆蓋了原來a變量的值,console結(jié)果10
最后在函數(shù)外部的console,顯然的這里全局變量已經(jīng)被重新賦值,所以console結(jié)果為10;

100/10/10

最后來一題:

var foo = 1;
function main(){
    alert(foo);
    var foo = 2;
    alert(this.foo)
    this.foo = 3;
};
// 請給出以下兩種方式調(diào)用函數(shù)時,alert的結(jié)果,并說明原因。
var m1 = main();        // undefined | 1
var m2 = new main();    // undefined | undefined

首先是m1,這里的main函數(shù)是普通調(diào)用,則按照普通函數(shù)處理。內(nèi)部var foo = 2會被提前聲明,所以第一個alert彈出undefined,之后賦值2
第二個alert調(diào)用的是this.foo,this引用此時指向window全局對象,所以彈出的是全局變量foo的值1;
最后將全局變量重新賦值為3;
但是m1的值是什么?是undefined。這個函數(shù)沒有指定return,默認返回undefined。

在來看m2,這里是構(gòu)造函數(shù)調(diào)用,當時函數(shù)內(nèi)部該執(zhí)行的會繼續(xù)執(zhí)行,但是我們肯定知道的是構(gòu)造函數(shù)的實例對象的引用會賦值給m2;
第一個alert不變,值為undefined,之后局部變量foo被賦值為2;
運行到第二個alert,這里的this引用指向誰?指向m2。等價于m2.foo,但是此時的m2未被定義(在下一行代碼)。所以alert彈出undefined。

可以看一下這篇文章:談談JS的全局變量跟局部變量 - 刀刀的專欄

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/82987.html

相關(guān)文章

  • JavaScript——this、全局變量局部變量混談

    摘要:再來看書中的例子變量引用了構(gòu)造函數(shù)新生成的變量,所以相當于與。而全局變量是全局對象的屬性。延伸知識點最近學,發(fā)現(xiàn)這幾個知識點最好形成思維導圖來理解作用域變量聲明提升全局對象全局變量引用上下文構(gòu)造函數(shù)原型鏈與原型。 全局變量 可以先看W3C:JavaScript 全局對象、MDN:this 全局變量,W3C里說得很清楚(JavaScript Window - 瀏覽器對象模型): sho...

    xiaokai 評論0 收藏0
  • [學習筆記] JavaScript 作用

    摘要:全局執(zhí)行環(huán)境的變量對象始終是作用域鏈中的最后一個變量對象。綜上,每個函數(shù)對應一個執(zhí)行環(huán)境,每個執(zhí)行環(huán)境對應一個變量對象,而多個變量對象構(gòu)成了作用域鏈,如果當前執(zhí)行環(huán)境是函數(shù),那么其活動對象在作用域鏈的前端。 1.幾個概念 先說幾個概念:函數(shù)、執(zhí)行環(huán)境、變量對象、作用域鏈、活動對象。這幾個東東之間有什么關(guān)系呢,往下看~ 函數(shù) 函數(shù)大家都知道,我想說的是,js中,在函數(shù)內(nèi)部有兩個特殊...

    ?xiaoxiao, 評論0 收藏0
  • js作用與命名空間

    摘要:全局變量函數(shù)內(nèi)的局部作用域和是函數(shù)內(nèi)的局部變量,而對的賦值將會覆蓋全局作用域內(nèi)的同名變量。命名空間只有一個全局作用域?qū)е碌某R婂e誤是命名沖突。另外兩種方式結(jié)論推薦使用匿名包裝器譯者注也就是自執(zhí)行的匿名函數(shù)來創(chuàng)建命名空間。 盡管 JavaScript 支持一對花括號創(chuàng)建的代碼段,但是并不支持塊級作用域; 而僅僅支持 函數(shù)作用域。 function test() { // 一個作用域 ...

    antyiwei 評論0 收藏0
  • 老生常談—Javascript作用變量提升、閉包

    摘要:局部變量在函數(shù)中聲明的變量,函數(shù)的參數(shù)作用域是局部性的,在函數(shù)體外,或者說的當前作用域的上層是無法直接讀取的。執(zhí)行結(jié)果這樣我們就在外層取得了函數(shù)內(nèi)部局部變量的也就是閉包實現(xiàn)從外部讀取局部變量的能力。 淺談作用域 ??當我們新建一個可以儲存變量的值,怎么才能讀取到這個變量呢?能訪問到這個變量,就說明符合作用域規(guī)則,作用域規(guī)則就可以說是js引擎讀取變量的規(guī)則。??在js中變量分為兩種,全局...

    zhiwei 評論0 收藏0
  • JS筆記四:作用變量(函數(shù))提升

    摘要:變量作用域一個變量的作用域表示這個變量存在的上下文。在這種情況下,僅僅函數(shù)聲明的函數(shù)體被提升到頂部。雖然我們無需用來修飾形式參數(shù),但是形式參數(shù)的確也是變量,并且被自動提升到次高的優(yōu)先級函數(shù)聲明。 關(guān)于作用域,變量提升,函數(shù)提升的個人理解 參考: 阮一峰的JavaScript參考教程2.7函數(shù)部分 思否上一篇關(guān)于作用域,提升的博客 一篇關(guān)于作用域和提升的個人博客 MockingBird...

    FuisonDesign 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<