js作用域与作用域链
一直對(duì)Js的作用域有點(diǎn)迷糊,今天偶然讀到JavaScript權(quán)威指南,立馬被吸引住了,寫的真不錯(cuò)。我看的是第六版本,相當(dāng)?shù)暮?#xff0c;大概1000多頁,Js博大精深,要熟悉精通需要大毅力大功夫。
一:函數(shù)作用域
? ?先看一小段代碼:
[javascript]?view plaincopy?
(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? ? 我們可以看到,由于函數(shù)作用域的特性,局部變量在整個(gè)函數(shù)體始終是由定義的,我們可以將變量聲明”提前“到函數(shù)體頂部,同時(shí)變量初始化還在原來位置。
為什么說Js沒有塊級(jí)作用域呢,有以下代碼為證:
?
[javascript]?view plaincopy都輸出是“l(fā)ocal",如果有塊級(jí)作用域,明顯if語句將創(chuàng)建局部變量name,并不會(huì)修改全局name,可是沒有這樣,所以Js沒有塊級(jí)作用域。
?
?
現(xiàn)在很好理解為什么會(huì)得出那樣的結(jié)果了。scope聲明覆蓋了全局的scope,但是還沒有賦值,所以輸出:”undefined“。
所以下面的代碼也就很好理解了。
?
[javascript]?view plaincopy輸出:2 ?”ifscope"
?
二:變量作用域
還是首先看一段代碼:
?
[javascript]?view plaincopy
就是上面的翻版,知識(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
當(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當(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 plaincopywith語句將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)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Mssql 跨域查询
- 下一篇: java9-1.类,抽象类,接口的综合小