麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 語言 > JavaScript > 正文

Javascript中的作用域和上下文深入理解

2024-05-06 16:22:40
字體:
來源:轉載
供稿:網友
這篇文章主要介紹了Javascript中的作用域和上下文深入理解,本文講解了作用域 VS 上下文、變量作用域、“this”上下文、執(zhí)行上下文(Execution Context)、作用域鏈等內容,需要的朋友可以參考下
 

概述

Javascript中的作用域和上下文的實現(xiàn)是Javascript語言獨有的特性,從某種程度上來說,Javascript語言是十分靈活的。Javascript中的函數(shù)可以采用各種各樣的上下文,作用域也可以被封裝和保存。正是由于這些特性,Javascript中也提供了很多很有用的設計模式。然而,作用域和上下文也是Javascript程序員在開發(fā)中經常迷惑的地方。
下面會向大家介紹Javascript中作用域和上下文的概念,以及它們的不同。

作用域 VS 上下文

首先要說明的很重要的一點是作用域和上下文并不是同一個概念,它們指代的并不是同一個東西。作為一個前端的菜逼,經常會看到一些文章把這兩個概念弄混,結果有些東西越看越不明白。這兩個概念貌似被混淆了很長一段時間了。因此,查了很多資料,簡單說明下這兩個概念。:stuck_out_tongue_closed_eyes:
在Javascript中,當一個函數(shù)被調用時都會有一個作用域和上下文和這個函數(shù)綁定在一起。從根本上來說,作用域是基于函數(shù)的而上下文是基于對象的。換句話說,作用域適用于函數(shù)被調用時函數(shù)中變量的訪問權限。上下文通常是指“this”關鍵字的值,“this”是擁有當前執(zhí)行代碼的對象的引用。

變量作用域

變量可以被定義在局域或全局作用域中,分別稱為局部變量和全局變量。全局變量是指在函數(shù)體外聲明的變量,在程序的任何地方都可以訪問全局變量。局部變量是指在函數(shù)體內定義的變量,它僅可以在函數(shù)體內或者嵌套的函數(shù)內被訪問,并且不能在函數(shù)外部被訪問。
Javascript目前并不支持塊級作用域(在if、switch、for等語句中定義的變量)。這意味著在塊內定義的變量,在塊外也可以訪問。但是,在ES6中,我們可以使用“let”關鍵字定義塊級作用域。
關于作用域的內容,大家可以查下別的資料,這部分內容相對簡單些。

“this”上下文

上下文(context)通常取決于函數(shù)被調用的方式。當函數(shù)作為對象的方法被調用時,“this”指代的是調用該函數(shù)的對象。

復制代碼代碼如下:

var obj={
    foo:function (){
        console.log(this === obj);
    }
};
obj.foo();   //輸出true

同樣,當我們使用“new”關鍵字創(chuàng)建新對象時,this引用的是新創(chuàng)建的對象。
復制代碼代碼如下:

function foo(){
    console.log(this);
}
foo();         //輸出window
var obj=new foo();     //輸出 foo {}

有一點需要注意的是,當全局作用域中的函數(shù)被被調用時,this引用的是全局對象,在瀏覽器環(huán)境中指的就是window。但是,如果在嚴格模式下運行代碼時,“this”被設置為“undefined”
執(zhí)行上下文(Execution Context)

 

Javascript是單線程的語言,這也就是說Javascript在瀏覽器中運行時,一次只能做一件事情,其他的事情將被方法隊列中,等待被處理。

1.當Javascript代碼文件被瀏覽器載入后,默認最新進入的是一個全局的執(zhí)行上下文。當在全局上下文中調用一個函數(shù)時,程序留就進入該被調用函數(shù)內,此時Javascript引擎就會為該函數(shù)創(chuàng)建一個新的執(zhí)行上下文,并且將其壓入到執(zhí)行上下文堆棧的頂部。瀏覽器總是執(zhí)行當前在堆棧頂部的上下文,一旦執(zhí)行完畢,該上下文就會從堆棧頂部被彈出,然后,進入其下的上下文執(zhí)行代碼。這樣,堆棧中的上下文就會被依次執(zhí)行并且彈出堆棧,直到回到全局的上下文。

2.一個執(zhí)行上下文可以被分為兩個階段:創(chuàng)建階段和執(zhí)行階段。在創(chuàng)建階段,javascript解釋器首先會創(chuàng)建一個變量對象(也成為“活動對象”,activation object)。活動對象由變量,函數(shù)聲明和參數(shù)組成。在這個階段,函數(shù)的作用域鏈被初始化,this引用的對象也被確定。接下來就是執(zhí)行階段,在這個階段,代碼被解釋并執(zhí)行。
在Javascript代碼中,可以有任意多個函數(shù)上下文,我們已經知道,當函數(shù)被調用時,Javascript解釋器就會創(chuàng)建一個新的上下文,同時會創(chuàng)建一個私有的作用域,函數(shù)內部聲明的任何變量都不能在當前函數(shù)作用域外部直接訪問。

3.通過上面的解釋,我們對函數(shù)的“執(zhí)行上下文”有了一個基本的概念,但是這里也是大家最容易迷惑的一個地方。Javascript中的“執(zhí)行上下文”主要是指作用域,而不是上面第四小節(jié)中指的“this上下文”。類似的容易混淆的概念在Javascript中還有很多,但是我們只要弄清楚了每個概念所指代的具體對象,就不會再迷惑,因此,這里也希望大家能夠真正的區(qū)分開“執(zhí)行上下文”和“this上下文”。

簡單的一句話概括來說,執(zhí)行上下文是與作用域相關的概念,雖然這樣說可能不太嚴謹。

作用域鏈

對每一個執(zhí)行上下文來說,都有一個作用域連跟它綁定在一起。作用域鏈包含了執(zhí)行上下文堆棧中的執(zhí)行上下文活動對象(activation object,聽起來有點繞口)。作用域鏈決定了變量的訪問和標識符的解析。

代碼示例:

復制代碼代碼如下:

function first(){
    second();
    function second(){
        third();
        function third(){
            fourth();
            function fourth(){
                //代碼
            }
        }
    }
}
first();

 

執(zhí)行上面的代碼,嵌套的函數(shù)都會被執(zhí)行。就上面的代碼來說,也會形成一個作用域鏈,作用域鏈從頂部到底部的順序為:fourth, third, second, first, global。函數(shù)fourth可以訪問全局作用域中的變量,并且可以訪問函數(shù)third, second, first中定義的任何變量。
有一點需要注意的是,在函數(shù)體內,局部變量的優(yōu)先級高于同名的全局變量。如果在函數(shù)內聲明的局部變量或函數(shù)參數(shù)中帶有的變量和全局變量重名,那么全局變量就被局部變量所覆蓋。
簡單來說,每次我們嘗試訪問一個變量時,程序都會在當前函數(shù)作用域內查找變量,如果找不到就沿著作用域鏈到該函數(shù)的上層去查找,直到找到該變量為止,如果找不到則返回undefined。

總結

這篇文章介紹了javascript中上下文和作用域的相關概念,javascript中還有幾個比較重要的概念,如閉包等,這些在以后自己弄明白了會寫成文章~~


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表

圖片精選

主站蜘蛛池模板: www.精品在线 | 色综av| 爽爽视频免费看 | 日韩一级电影在线观看 | 国产手机国产手机在线 | 成人网在线观看 | 亚洲综合视频网站 | 国产成人小视频在线观看 | av免费在线网站 | 快播av在线 | 久久久久久久久久91 | www.9191.com| 国产精品成人免费一区久久羞羞 | 国产亚洲综合一区二区 | 91午夜免费视频 | 国产一级免费不卡 | 1314成人网 | 免费一级毛片电影 | 国产日本欧美在线观看 | 欧美3p激情一区二区三区猛视频 | 日本黄色大片免费 | 免费的性生活视频 | 欧美成人亚洲 | 精品在线视频观看 | 欧美激情精品久久久久久黑人 | 精品国产91久久久久久浪潮蜜月 | 男男啪羞羞视频网站 | h视频免费观看 | 男女生羞羞视频网站在线观看 | 永久免费不卡在线观看黄网站 | 久色视频网站 | xxxⅹ96日本护士hd | 羞羞电影在线观看 | 国产精品99久久久久久久女警 | 一区二区三区视频在线观看 | 国产三级国产精品国产普男人 | 成人福利电影在线观看 | 大逼逼影院 | 日本在线精品视频 | 久久精品亚洲一区二区 | 欧美成人一区二区三区 |