日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

js作用域与作用域链

發(fā)布時(shí)間:2023/12/18 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 js作用域与作用域链 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一直對(duì)Js的作用域有點(diǎn)迷糊,今天偶然讀到JavaScript權(quán)威指南,立馬被吸引住了,寫的真不錯(cuò)。我看的是第六版本,相當(dāng)?shù)暮?#xff0c;大概1000多頁,Js博大精深,要熟悉精通需要大毅力大功夫。

一:函數(shù)作用域

? ?先看一小段代碼:

[javascript]?view plaincopy
  • var?scope="global";??
  • function?t(){??
  • ????console.log(scope);??
  • ????var?scope="local"??
  • ????console.log(scope);??
  • }??
  • t();??
  • ?

    (PS: console.log()是firebug提供的調(diào)試工具,很好用,有興趣的童鞋可以用下,比瀏覽器+alert好用多了)

    第一句輸出的是: "undefined",而不是 "global"

    第二講輸出的是:"local"

    ? 你可能會(huì)認(rèn)為第一句會(huì)輸出:"global",因?yàn)榇a還沒執(zhí)行var scope="local",所以肯定會(huì)輸出“global"。

    ? 我說這想法完全沒錯(cuò),只不過用錯(cuò)了對(duì)象。我們首先要區(qū)分Javascript的函數(shù)作用域與我們熟知的C/C++等的塊級(jí)作用域。

    ? 在C/C++中,花括號(hào)內(nèi)中的每一段代碼都具有各自的作用域,而且變量在聲明它們的代碼段之外是不可見的。而Javascript壓根沒有塊級(jí)作用域,而是函數(shù)作用域.

    所謂函數(shù)作用域就是說:-》變量在聲明它們的函數(shù)體以及這個(gè)函數(shù)體嵌套的任意函數(shù)體內(nèi)都是有定義的。

    所以根據(jù)函數(shù)作用域的意思,可以將上述代碼重寫如下:

    ?

    [javascript]?view plaincopy
  • var?scope="global";??
  • function?t(){??
  • ????var?scope;??
  • ????console.log(scope);??
  • ????scope="local"??
  • ????console.log(scope);??
  • }??
  • t();??
  • ? ? 我們可以看到,由于函數(shù)作用域的特性,局部變量在整個(gè)函數(shù)體始終是由定義的,我們可以將變量聲明”提前“到函數(shù)體頂部,同時(shí)變量初始化還在原來位置。

    為什么說Js沒有塊級(jí)作用域呢,有以下代碼為證:

    ?

    [javascript]?view plaincopy
  • var?name="global";??
  • if(true){??
  • ????var?name="local";??
  • ????console.log(name)??
  • }??
  • console.log(name);??
  • 都輸出是“l(fā)ocal",如果有塊級(jí)作用域,明顯if語句將創(chuàng)建局部變量name,并不會(huì)修改全局name,可是沒有這樣,所以Js沒有塊級(jí)作用域。

    ?

    ?

    現(xiàn)在很好理解為什么會(huì)得出那樣的結(jié)果了。scope聲明覆蓋了全局的scope,但是還沒有賦值,所以輸出:”undefined“。

    所以下面的代碼也就很好理解了。

    ?

    [javascript]?view plaincopy
  • function?t(flag){??
  • ????if(flag){??
  • ????????var?s="ifscope";??
  • ????????for(var?i=0;i<2;i++)???
  • ????????????;??
  • ????}??
  • ????console.log(i);??
  • ????console.log(s);??
  • }??
  • t(true);??
  • 輸出:2 ?”ifscope"


    ?

    二:變量作用域

    還是首先看一段代碼:

    ?

    [javascript]?view plaincopy
  • function?t(flag){??
  • ????if(flag){??
  • ????????s="ifscope";??
  • ????????for(var?i=0;i<2;i++)???
  • ????????????;??
  • ????}??
  • ????console.log(i);??
  • }??
  • t(true);??
  • console.log(s);??

  • 就是上面的翻版,知識(shí)將聲明s中的var去掉。

    ?

    程序會(huì)報(bào)錯(cuò)還是輸出“ifscope"呢?

    讓我揭開謎底吧,會(huì)輸出:”ifscope"

    這主要是Js中沒有用var聲明的變量都是全局變量,而且是頂層對(duì)象的屬性。

    所以你用console.log(window.s)也是會(huì)輸出“ifconfig"

    ?

    當(dāng)使用var聲明一個(gè)變量時(shí),創(chuàng)建的這個(gè)屬性是不可配置的,也就是說無法通過delete運(yùn)算符刪除

    var name=1 ? ?->不可刪除

    sex=”girl“ ? ? ? ? ->可刪除

    this.age=22 ? ?->可刪除

    ?

    三:作用域鏈

    先來看一段代碼:

    ?

    [javascript]?view plaincopy
  • name="lwy";??
  • function?t(){??
  • ????var?name="tlwy";??
  • ????function?s(){??
  • ????????var?name="slwy";??
  • ????????console.log(name);??
  • ????}??
  • ????function?ss(){??
  • ????????console.log(name);??
  • ????}??
  • ????s();??
  • ????ss();??
  • }??
  • t();??

  • 當(dāng)執(zhí)行s時(shí),將創(chuàng)建函數(shù)s的執(zhí)行環(huán)境(調(diào)用對(duì)象),并將該對(duì)象置于鏈表開頭,然后將函數(shù)t的調(diào)用對(duì)象鏈接在之后,最后是全局對(duì)象。然后從鏈表開頭尋找變量name,很明顯

    ?

    name是"slwy"。

    但執(zhí)行ss()時(shí),作用域鏈?zhǔn)?#xff1a; ss()->t()->window,所以name是”tlwy"

    下面看一個(gè)很容易犯錯(cuò)的例子:

    ?

    [html]?view plaincopy
  • <html>??
  • <head>??
  • <script?type="text/javascript">??
  • function?buttonInit(){??
  • ????for(var?i=1;i<4;i++){??
  • ????????var?b=document.getElementById("button"+i);??
  • ????????b.addEventListener("click",function(){?alert("Button"+i);},false);??
  • ????}??
  • }??
  • window.οnlοad=buttonInit;??
  • </script>??
  • </head>??
  • <body>??
  • <button?id="button1">Button1</button>??
  • <button?id="button2">Button2</button>??
  • <button?id="button3">Button3</button>??
  • </body>??
  • </html>??
  • 當(dāng)文檔加載完畢,給幾個(gè)按鈕注冊(cè)點(diǎn)擊事件,當(dāng)我們點(diǎn)擊按鈕時(shí),會(huì)彈出什么提示框呢?

    ?

    很容易犯錯(cuò),對(duì)是的,三個(gè)按鈕都是彈出:"Button4",你答對(duì)了嗎?

    當(dāng)注冊(cè)事件結(jié)束后,i的值為4,當(dāng)點(diǎn)擊按鈕時(shí),事件函數(shù)即function(){ alert("Button"+i);}這個(gè)匿名函數(shù)中沒有i,根據(jù)作用域鏈,所以到buttonInit函數(shù)中找,此時(shí)i的值為4,

    所以彈出”button4“。

    ?

    四:with語句

    說到作用域鏈,不得不說with語句。with語句主要用來臨時(shí)擴(kuò)展作用域鏈,將語句中的對(duì)象添加到作用域的頭部。

    看下面代碼

    [javascript]?view plaincopy
  • person={name:"yhb",age:22,height:175,wife:{name:"lwy",age:21}};??
  • with(person.wife){??
  • ????console.log(name);??
  • }??
  • with語句將person.wife添加到當(dāng)前作用域鏈的頭部,所以輸出的就是:“l(fā)wy".

    ?

    with語句結(jié)束后,作用域鏈恢復(fù)正常。

    轉(zhuǎn)載于:https://www.cnblogs.com/ly-china/p/5433709.html

    總結(jié)

    以上是生活随笔為你收集整理的js作用域与作用域链的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。