最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

老生常談原生JS執(zhí)行環(huán)境與作用域

 更新時間:2016年11月22日 08:12:06   投稿:jingxian  
下面小編就為大家?guī)硪黄仙U勗鶭S執(zhí)行環(huán)境與作用域。小編覺得挺不錯的,希望對大家有所幫助。一起跟隨小編過來看看吧,祝大家游戲愉快哦

首先,我們要知道執(zhí)行環(huán)境和作用域是兩個完全不同的概念。

函數的每次調用都有與之緊密相關的作用域和執(zhí)行環(huán)境。從根本上來說,作用域是基于函數的,而執(zhí)行環(huán)境是基于對象的(例如:全局執(zhí)行環(huán)境即window對象)。

換句話說,作用域涉及到所被調用函數中的變量訪問,并且不同的調用場景是不一樣的。執(zhí)行環(huán)境始終是this關鍵字的值,它是擁有當前所執(zhí)行代碼的對象的引用。每個執(zhí)行環(huán)境都有一個與之關聯(lián)的變量對象,環(huán)境中定義的所有變量和函數都保存在這個對象中。雖然我們編寫的代碼無法訪問這個對象,但解析器在處理數據時會在后臺使用它。

執(zhí)行環(huán)境(也稱執(zhí)行上下文–execution context)

當JavaScript解釋器初始化執(zhí)行代碼時,它首先默認進入全局執(zhí)行環(huán)境,從此刻開始,函數的每次調用都會創(chuàng)建一個新的執(zhí)行環(huán)境。

每個函數都有自己的執(zhí)行環(huán)境。當執(zhí)行流進入一個函數時,函數的環(huán)境就會被推入一個環(huán)境棧中(execution stack)。在函數執(zhí)行完后,棧將其環(huán)境彈出,把控制權返回給之前的執(zhí)行環(huán)境。ECMAScript程序中的執(zhí)行流正是由這個便利的機制控制著。

執(zhí)行環(huán)境可以分為創(chuàng)建和執(zhí)行兩個階段。在創(chuàng)建階段,解析器首先會創(chuàng)建一個變量對象(variable object,也稱為活動對象 activation object),它由定義在執(zhí)行環(huán)境中的變量、函數聲明、和參數組成。在這個階段,作用域鏈會被初始化,this的值也會被最終確定。在執(zhí)行階段,代碼被解釋執(zhí)行。

Demo:

<script type="text/javascript">
  function Fn1(){
    function Fn2(){
      alert(document.body.tagName);//BODY
      //other code...
    }
    Fn2();
  }
  Fn1();
  //code here
</script>

小結

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

此外還要注意一下幾點:

單線程

同步執(zhí)行

唯一的全局執(zhí)行環(huán)境

局部執(zhí)行環(huán)境的個數沒有限制

每次某個函數被調用,就會有個新的局部執(zhí)行環(huán)境為其創(chuàng)建,即使是多次調用的自身函數(即一個函數被調用多次,也會創(chuàng)建多個不同的局部執(zhí)行環(huán)境)。

作用域

當代碼在一個環(huán)境中執(zhí)行時,會創(chuàng)建變量對象的一個作用域鏈(scope chain)。作用域鏈的用途是保證對執(zhí)行環(huán)境有權訪問的所有變量和函數的有序訪問。

作用域鏈包含了執(zhí)行環(huán)境棧中的每個執(zhí)行環(huán)境對應的變量對象。通過作用域鏈,可以決定變量的訪問和標識符的解析。

注意:全局執(zhí)行環(huán)境的變量對象始終都是作用域鏈的最后一個對象。

在訪問變量時,就必須存在一個可見性的問題(內層環(huán)境可以訪問外層中的變量和函數,而外層環(huán)境不能訪問內層的變量和函數)。更深入的說,當訪問一個變量或調用一個函數時,JavaScript引擎將不同執(zhí)行環(huán)境中的變量對象按照規(guī)則構建一個鏈表,在訪問一個變量時,先在鏈表的第一個變量對象上查找,如果沒有找到則繼續(xù)在第二個變量對象上查找,直到搜索到全局執(zhí)行環(huán)境的變量對象即window對象。這也就形成了Scope Chain的概念。

作用域鏈圖,清楚的表達了執(zhí)行環(huán)境與作用域的關系(一一對應的關系),作用域與作用域之間的關系(鏈表結構,由上至下的關系)。

Demo:

var color = "blue";
function changeColor(){
 var anotherColor = "red";
 function swapColors(){
  var tempColor = anotherColor;
  anotherColor = color;
  color = tempColor;
  // 這里可以訪問color, anotherColor, 和 tempColor
 }
 // 這里可以訪問color 和 anotherColor,但是不能訪問 tempColor
 swapColors();
}
changeColor();
// 這里只能訪問color
console.log("Color is now " + color);

上述代碼一共包括三個執(zhí)行環(huán)境:全局執(zhí)行環(huán)境、changeColor()的局部執(zhí)行環(huán)境、swapColors()的局部執(zhí)行環(huán)境。

全局環(huán)境有一個變量color和一個函數changecolor();

changecolor()函數的局部環(huán)境中具有一個anothercolor屬性和一個swapcolors函數,當然,changecolor函數中可以訪問自身以及它外圍(即全局環(huán)境)中的變量;

swapcolor()函數的局部環(huán)境中具有一個變量tempcolor。在該函數內部可以訪問上面的兩個環(huán)境(changecolor和window)中的所有變量,因為那兩個環(huán)境都是它的父執(zhí)行環(huán)境。

上述代碼的作用域鏈如下圖所示:

從上圖發(fā)現。內部環(huán)境可以通過作用域鏈訪問所有的外部環(huán)境,但是外部環(huán)境不能訪問內部環(huán)境中的任何變量和函數。

標識符解析(變量名或函數名搜索)是沿著作用域鏈一級一級地搜索標識符的過程。搜索過程始終從作用域鏈的前端開始,然后逐級地向后(全局執(zhí)行環(huán)境)回溯,直到找到標識符為止。

執(zhí)行環(huán)境與作用域的區(qū)別與聯(lián)系

執(zhí)行環(huán)境為全局執(zhí)行環(huán)境和局部執(zhí)行環(huán)境,局部執(zhí)行環(huán)境是函數執(zhí)行過程中創(chuàng)建的。

作用域鏈是基于執(zhí)行環(huán)境的變量對象的,由所有執(zhí)行環(huán)境的變量對象(對于函數而言是活動對象,因為在函數執(zhí)行環(huán)境中,變量對象是不能直接訪問的,此時由活動對象(activation object,縮寫為AO)扮演VO(變量對象)的角色。)共同組成。

當代碼在一個環(huán)境中執(zhí)行時,會創(chuàng)建變量對象的一個作用域鏈。作用域鏈的用途:是保證對執(zhí)行環(huán)境有權訪問的所有變量和函數的有序訪問。作用域鏈的前端,始終都是當前執(zhí)行的代碼所在環(huán)境的變量對象。

小練習

<script type="text/javascript">
(function(){
  a= 5;
  console.log(window.a);//undefined
  var a = 1;//這里會發(fā)生變量聲明提升
  console.log(a);//1
})();
</script>

window.a之所以是undefined,是因為var a = 1;發(fā)生了變量聲明提升。相當于如下代碼:

<script type="text/javascript">
(function(){
  var a;//a是局部變量
  a = 5;//這里局部環(huán)境中有a,就不會找全局中的
  console.log(window.a);//undefined
  a = 1;//這里會發(fā)生變量聲明提升
  console.log(a);//1
})();
</script>

以上就是小編為大家?guī)淼睦仙U勗鶭S執(zhí)行環(huán)境與作用域全部內容了,希望大家多多支持腳本之家~

相關文章

  • js仿百度貼吧驗證碼特效實例代碼

    js仿百度貼吧驗證碼特效實例代碼

    這篇文章主要介紹了js仿百度貼吧驗證碼特效實例代碼,有需要的朋友可以參考一下
    2014-01-01
  • 談談為什么你的 JavaScript 代碼如此冗長

    談談為什么你的 JavaScript 代碼如此冗長

    這篇文章主要介紹了談談為什么你的 JavaScript 代碼如此冗長,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-01-01
  • Popup對象實現右鍵菜單

    Popup對象實現右鍵菜單

    Popup對象實現右鍵菜單...
    2006-09-09
  • 純js網頁畫板(Graphics)類簡介及實現代碼

    純js網頁畫板(Graphics)類簡介及實現代碼

    今天需要在網頁上畫一個圖譜,想到用JS,經過學習,和網上搜索,經過整理優(yōu)化得到下面代碼,注意不是用HTML5的canvas,而是用的純js,需要了解的朋友可以參考下
    2012-12-12
  • 微信公眾平臺獲取access_token的方法步驟

    微信公眾平臺獲取access_token的方法步驟

    這篇文章主要介紹了微信公眾平臺獲取access_token的方法步驟,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-03-03
  • js+html實現周歲年齡計算器

    js+html實現周歲年齡計算器

    這篇文章主要為大家詳細介紹了js+html實現周歲年齡計算器的方法,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-06-06
  • JS學習筆記之數組去重實現方法小結

    JS學習筆記之數組去重實現方法小結

    這篇文章主要介紹了JS學習筆記之數組去重實現方法,結合實例形式總結分析了javascript數組去重的5種常見實現方法及相關操作技巧,需要的朋友可以參考下
    2019-05-05
  • JS利用正則表達式實現簡單的密碼強弱判斷實例

    JS利用正則表達式實現簡單的密碼強弱判斷實例

    這篇文章主要給大家介紹了關于JS利用正則表達式實現簡單的密碼強弱判斷的相關資料,實現后的效果非常簡單,但也挺實用的,文中給出了詳細的示例代碼供大家參考學習,需要的朋友們下面來一起看看吧。
    2017-06-06
  • 教學演示-UBB,剪貼板,textRange及其他

    教學演示-UBB,剪貼板,textRange及其他

    教學演示-UBB,剪貼板,textRange及其他...
    2006-07-07
  • JavaScript創(chuàng)建對象的四種常用模式實例分析

    JavaScript創(chuàng)建對象的四種常用模式實例分析

    這篇文章主要介紹了JavaScript創(chuàng)建對象的四種常用模式,結合實例形式分析了javascript使用工廠模式、構造函數模式、原型模式及動態(tài)原型模式創(chuàng)建對象的相關操作技巧與注意事項,需要的朋友可以參考下
    2019-01-01

最新評論

景宁| 东宁县| 临漳县| 屏山县| 延长县| 广元市| 宁远县| 建宁县| 磐石市| 东光县| 芦山县| 当涂县| 巴林左旗| 喀喇沁旗| 黄大仙区| 罗田县| 会同县| 和龙市| 新昌县| 东乌珠穆沁旗| 淮阳县| 文成县| 剑川县| 京山县| 兰坪| 西华县| 潼关县| 新田县| 高台县| 营山县| 唐山市| 宁津县| 西乡县| 武川县| 肇庆市| 陆良县| 锡林郭勒盟| 塔城市| 罗山县| 荆门市| 大埔县|