成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

javascript作用域鏈與執(zhí)行環(huán)境的示例分析

這篇文章主要介紹javascript作用域鏈與執(zhí)行環(huán)境的示例分析,文中介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們一定要看完!

創(chuàng)新互聯(lián)專注于企業(yè)成都全網(wǎng)營銷、網(wǎng)站重做改版、建平網(wǎng)站定制設(shè)計、自適應(yīng)品牌網(wǎng)站建設(shè)、H5頁面制作、商城網(wǎng)站建設(shè)、集團(tuán)公司官網(wǎng)建設(shè)、外貿(mào)網(wǎng)站制作、高端網(wǎng)站制作、響應(yīng)式網(wǎng)頁設(shè)計等建站業(yè)務(wù),價格優(yōu)惠性價比高,為建平等各大城市提供網(wǎng)站開發(fā)制作服務(wù)。

作用域、作用域鏈、執(zhí)行環(huán)境、執(zhí)行環(huán)境棧以及this的概念在javascript中非常重要,本人經(jīng)常弄混淆,這里梳理一下;

  • 局部作用域函數(shù)內(nèi)部的區(qū)域,全局作用域就是window;

  • 作用域鏈取決于函數(shù)被聲明時的位置,解析標(biāo)識符的時候就先找當(dāng)前作用域,再向外查找,直到全局,這樣一個順序;和函數(shù)在哪里調(diào)用無關(guān);

  • 執(zhí)行環(huán)境就是函數(shù)可訪問的數(shù)據(jù)和變量的集合,也就是函數(shù)的作用域鏈上的所有數(shù)據(jù)和變量;

  • 執(zhí)行環(huán)境棧就是根據(jù)代碼執(zhí)行順序,各執(zhí)行環(huán)境按照棧的形式逐層訪問,并且用完了退出來扔掉;如果當(dāng)前執(zhí)行環(huán)境(存放當(dāng)前作用域鏈里的數(shù)據(jù)和變量)找不到變量,那就是找不到了,不會往之前的那個執(zhí)行環(huán)境查找,它和作用域鏈?zhǔn)遣煌模?/p>

  • this是一個對象,它取決于是誰執(zhí)行的,誰執(zhí)行那就是誰;(this的概念還是不太清楚,這里寫的有點萬金油,過兩天再來修正) 

作用域

JavaScript沒有塊級作用域的概念,只有函數(shù)級作用域:變量在聲明它們的函數(shù)體及其子函數(shù)內(nèi)是可見的。

作用域就是變量和函數(shù)的可訪問范圍,控制著變量和函數(shù)的可見性與生命周期,在JavaScript中變量的作用域有全局作用域和局部作用域。

變量沒有在函數(shù)內(nèi)聲明或者聲明的時候沒有帶var就是全局變量,擁有全局作用域;

 <script type="text/javascript">
 function test1(){
  a = 1;//全局變量,只有在當(dāng)前函數(shù)運(yùn)行時,才有效
  }
 test1();
 console.log(a);//1 注意test1函數(shù)必須運(yùn)行,不然找不到a
 </script>

全局變量可以當(dāng)做window對象的屬性用,他們是一樣的; 

<script type="text/javascript"> 
 var b = 1;//全局變量
 console.log(b === window.b);//true 全局變量可以當(dāng)做window對象的屬性用,他們是一樣的;
</script>

window對象的所有屬性擁有全局作用域,在代碼任何地方都可以訪問;

函數(shù)內(nèi)部聲明的變量就是局部變量,只能在函數(shù)體內(nèi)使用,函數(shù)的參數(shù)雖然沒有使用var但仍然是局部變量。

 <script type="text/javascript"> 
   var c = 1;//全局變量
//   console.log(d);//ReferenceError: d is not defined 引用錯誤,當(dāng)前作用域就是最外層作用域,依然找不到d
   function test2(d){
    console.log(c);//1 全局變量,哪都可以訪問;(先找當(dāng)前作用域,找不到,就向外層作用域找,直到window最外層,找到了)
    console.log(d);//3 形參是局部變量,只有當(dāng)前作用域下可以訪問
   }
   test2(3);
  </script>

作用域鏈

作用域鏈取決于函數(shù)被聲明時的位置,解析標(biāo)識符的時候就先從當(dāng)前作用域開始找,在當(dāng)前作用域中無法找到時,引擎就會在外層嵌套的作用域中繼續(xù)查找,直到找到該變量,或抵達(dá)最外層的作用域(也就是全局作用域)為止;它的路線已經(jīng)被定死了,和函數(shù)在哪里運(yùn)行無關(guān);

<script type="text/javascript">
   var a = 1;
   var b = 2;
   var c = 3;
   var d = 4;
   function inner(d) {//它的作用域鏈?zhǔn)莍nner---全局
    var c = 8;
    console.log(a);//1 當(dāng)前作用域找不到a,去全局作用域找到了a=1
    console.log(b);//2 當(dāng)前作用域找不到b,去全局作用域找到了b=2
    console.log(c);//8 當(dāng)前作用域找到了c=8
    console.log(d);//7 當(dāng)前作用域找到了d=7,形參也是局部作用域
   // console.log(e);//ReferenceError: e is not defined 引用錯誤,找不到e, 它的作用域鏈?zhǔn)莍nner---全局
    console.log(a+b+c+d);//18
   }
   function outter(e) {
    var a = 5;//inner()的作用域鏈?zhǔn)莍nner---全局,所以這個a相當(dāng)于無效
    var b = 6;//inner()的作用域鏈?zhǔn)莍nner---全局,所以這個a相當(dāng)于無效
    inner(7);
   }
   outter(999);//這個999無效,里面的e根本找不到
</script>

在多層的嵌套作用域中可以定義同名的標(biāo)識符,這叫作“遮蔽效應(yīng)”,內(nèi)部的標(biāo)識符“遮蔽”了外部的標(biāo)識符

通過window.a這種技術(shù)可以訪問那些被同名變量所遮蔽的全局變量。但非全局的變量如果被遮蔽了,無論如何都無法被訪問到;

<script type="text/javascript">
   var a = 'Lily';
   var b = 'Lucy';
   function outer() {
    var b = 'Jesica';
    var c = 'Susan';
    function inner(c) {
     console.log(a);//Lily 
     console.log(window.b);//Lucy
     console.log(b);//Jesica
     console.log(c);//Jenifer
    }
    inner('Jenifer');
   }
   outer();
</script>

執(zhí)行環(huán)境

執(zhí)行環(huán)境(execution context),也叫執(zhí)行上下文。每個執(zhí)行環(huán)境都有一個變量對象(variable object),保存函數(shù)可訪問的所有變量和數(shù)據(jù)(也就是函數(shù)的作用域鏈上的所有數(shù)據(jù)和變量)。我們的代碼訪問不到它,它是給引擎使用的;

執(zhí)行環(huán)境棧,當(dāng)執(zhí)行進(jìn)入一個函數(shù)時,函數(shù)的執(zhí)行環(huán)境就會被推入一個棧中。而在函數(shù)執(zhí)行完之后,棧將其執(zhí)行環(huán)境移除,它里面的變量和數(shù)據(jù)會被標(biāo)記清除,等待垃圾回收,再把控制權(quán)返回給之前的執(zhí)行環(huán)境。javascript程序中的執(zhí)行正是由這個機(jī)制控制著;

需要注意的是如果當(dāng)前執(zhí)行環(huán)境(存放當(dāng)前作用域鏈里的數(shù)據(jù)和變量)找不到變量,那就是找不到了,不會往之前的那個執(zhí)行環(huán)境查找,和作用域鏈?zhǔn)遣灰粯拥模?/strong>

代碼的執(zhí)行順序也不全是一行一行的執(zhí)行,而是和函數(shù)的調(diào)用順序有關(guān):

  • 代碼進(jìn)入全局執(zhí)行環(huán)境,全局執(zhí)行環(huán)境放入環(huán)境棧;

  • 當(dāng)執(zhí)行到一個函數(shù)時,就把這個函數(shù)的執(zhí)行環(huán)境推入到環(huán)境棧頂端,之前的執(zhí)行環(huán)境往后;

  • 全局執(zhí)行環(huán)境最先進(jìn)入,所以一直在底端;就和棧的概念差不多;

  • 函數(shù)執(zhí)行完之后,再把它的執(zhí)行環(huán)境從作用域鏈頂端移除,它保存的數(shù)據(jù)和函數(shù)都被標(biāo)記清除,等待垃圾回收;

  • 控制權(quán)交給之前的執(zhí)行環(huán)境,繼續(xù)往下執(zhí)行;

  • 當(dāng)頁面關(guān)閉時,全局執(zhí)行環(huán)境才銷毀;

<script type="text/javascript">
 var a = 1;
 var b = 2;
 var c = 3;
 var d = 4;
 function inner(d) {//它的作用域鏈?zhǔn)莍nner---全局
  var c = 8;
  console.log(a);//1 當(dāng)前作用域找不到a,去全局作用域找到了a=1
  console.log(b);//2 當(dāng)前作用域找不到b,去全局作用域找到了b=2
  console.log(c);//8 當(dāng)前作用域找到了c=8
  console.log(d);//7 當(dāng)前作用域找到了d=7,形參也是局部作用域
 // console.log(e);//ReferenceError: e is not defined 引用錯誤,找不到e, 它的作用域鏈?zhǔn)莍nner---全局
  console.log(a+b+c+d);//18
 }
 function outter(e) {
  var a = 5;//inner()的作用域鏈?zhǔn)莍nner---全局,所以這個a相當(dāng)于無效
  var b = 6;//inner()的作用域鏈?zhǔn)莍nner---全局,所以這個a相當(dāng)于無效
  inner(7);
 }
 outter(999);//這個999無效,里面的e根本找不到
</script>

以上代碼的執(zhí)行順序:

代碼執(zhí)行進(jìn)入全局執(zhí)行環(huán)境,并對全局執(zhí)行環(huán)境中的代碼進(jìn)入聲明提升;    
執(zhí)行第2行,賦值a=1; 然后第3行賦值b=2; 然后第4行賦值c=3; 然后第5行賦值d=4;
執(zhí)行第20行,調(diào)用outer(999)函數(shù),然后進(jìn)入outer(999)函數(shù)執(zhí)行環(huán)境,聲明提升,并將實參999傳給形參e;現(xiàn)在環(huán)境棧中有兩個執(zhí)行環(huán)境,outer(999)是當(dāng)前執(zhí)行環(huán)境;
執(zhí)行第16行,賦值a=5; 然后第17行賦值b=6;    
執(zhí)行第18行,調(diào)用inner(7)函數(shù),然后進(jìn)入inner(7)函數(shù)執(zhí)行環(huán)境,聲明提升,并將實參7傳給形參d;
執(zhí)行第7行,賦值c=8; 然后運(yùn)算并輸出; 

代碼優(yōu)化

由于在作用域鏈上查找變量是需要消耗性能的,我們應(yīng)該盡快的找到變量,所以在函數(shù)多層嵌套的時候,我們應(yīng)盡可能的使用函數(shù)內(nèi)部的局部變量;

我們在函數(shù)內(nèi)部使用全局變量可以說是一種跨作用域操作,如果某個跨作用域的值在函數(shù)的內(nèi)部被多次使用,那么我們就把它存儲到局部變量里,這樣可以提高性能。

以上是“javascript作用域鏈與執(zhí)行環(huán)境的示例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對大家有幫助,更多相關(guān)知識,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!

網(wǎng)頁題目:javascript作用域鏈與執(zhí)行環(huán)境的示例分析
標(biāo)題路徑:http://jinyejixie.com/article8/ipejop.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供動態(tài)網(wǎng)站、手機(jī)網(wǎng)站建設(shè)、外貿(mào)建站、網(wǎng)站內(nèi)鏈、用戶體驗、全網(wǎng)營銷推廣

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

遂宁市| 仁怀市| 博客| 永丰县| 通江县| 抚远县| 贞丰县| 扎囊县| 板桥市| 临潭县| 都兰县| 武川县| 曲靖市| 新营市| 扎囊县| 固始县| 永泰县| 兰坪| 扎囊县| 永泰县| 静宁县| 万年县| 元氏县| 湘阴县| 皋兰县| 阿荣旗| 寿宁县| 泽普县| 常州市| 宁陕县| 牟定县| 弥渡县| 册亨县| 香港 | 阿坝| 濮阳县| 陇南市| 肃南| 灵台县| 阿坝县| 始兴县|