国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 編程 > JavaScript > 正文

Javascript變量的作用域和作用域鏈詳解

2019-11-20 12:47:34
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

工作這幾年,js學(xué)的不是很好,正好周末有些閑時(shí)間,索性買本《js權(quán)威指南》,大名鼎鼎的犀牛書,好好的把js深入的看一看。買過(guò)這本書的第一印象就是賊厚,不過(guò)后面有一半部分都是參考手冊(cè)。

一:作用域

  說(shuō)起變量第一個(gè)要說(shuō)到的肯定就是作用域,正是因?yàn)椴皇煜S的作用域,往往就會(huì)把面向?qū)ο蟮淖饔糜驈埞诶畲鳎吘褂行〇|西總是習(xí)慣性的這樣,但是并不是每次照搬都是可以的,那么下一個(gè)問(wèn)題就來(lái)了,js到底是什么作用域,當(dāng)然是函數(shù)作用域了,我們的瀏覽器就是一個(gè)被實(shí)例化的window對(duì)象,如果在window下定義一個(gè)name字段,那么name字段就具有window這個(gè)函數(shù)作用域,也就是在window下都是可以訪問(wèn)的,如果在window下定義一個(gè)function ctrip,然后里面再定義一個(gè)name,那么這個(gè)新定義的name只能在ctrip函數(shù)下通用,而老的name繼續(xù)在window下通用,舉個(gè)例子。

從圖中可以看出兩點(diǎn):

1: 在window下定義了一個(gè)name,居然還可以在function下定義一個(gè)重名的name,這個(gè)在C#里面是不可想象的。

2:在JS下就可以做到眼瞎,它只認(rèn)自己的作用域,所以就出現(xiàn)了第一個(gè)"second",你可能覺(jué)得這個(gè)沒(méi)有什么稀奇的地方,這是因?yàn)榭赡苣氵€沒(méi)有真正理解什么是函數(shù)作用域,解析器在執(zhí)行ctrip的時(shí)候,第一件事情就是尋找ctrip下的所有局部變量,然后再執(zhí)行后續(xù)語(yǔ)句,既然是先尋找,那么var name="second"這條語(yǔ)句定義在ctrip中任何位置都是可以的,下面我們把語(yǔ)句調(diào)換過(guò)來(lái)。

可以看到在ctrip函數(shù)下,第一個(gè)console.log輸出的是undefined,這個(gè)結(jié)果可以證實(shí),確實(shí)做了第一件事情是收集到了name這個(gè)局部變量,可能有人說(shuō)為什么沒(méi)有變成”second“,那是因?yàn)槌跏蓟僮鞅仨毷侵鹫Z(yǔ)句執(zhí)行,所以在ctrip函數(shù)中執(zhí)行console.log(name)時(shí),此時(shí)解析器只知道有一個(gè)未賦值的變量name,所以就console的時(shí)候就是undefined了。

二:作用域鏈

  從上面的這個(gè)例子中我們也很清楚的知道了,在function中定義的變量只具有function范圍內(nèi)的作用域,同時(shí)我們也看到上面這個(gè)例子只是一層嵌套,window是個(gè)大的function,里面是一個(gè)ctrip的function,同樣的道理也可以延伸到多層嵌套,比如三層,四層。。。。N層,這些層就形成了一個(gè)鏈?zhǔn)浇Y(jié)構(gòu)。

從圖中可以看到,我在ctrip下再定義了一個(gè)plane函數(shù),這樣的話就有三層了,輸出的結(jié)果也是我們希望看到的,每層的name只在自己的作用域范圍

內(nèi)生效,但是下面有一個(gè)問(wèn)題來(lái)了,有一天我傻逼了,在定義plane的函數(shù)時(shí),把 var name="third" 中的var忘記寫了,那么這個(gè)時(shí)候,plane中的

name到底是什么值呢? 是first還是second呢?

復(fù)制代碼 代碼如下:

var name="first";
function ctrip(){
  var name="second";
  function plane(){
     name="third";
     console.log(name);
  }
  plane();
  console.log(name);
}
ctrip();
console.log(name);

現(xiàn)在就是考驗(yàn)?zāi)闶欠裾娴亩俗饔糜蜴湥屑?xì)想想會(huì)發(fā)現(xiàn),當(dāng)代碼執(zhí)行到plane函數(shù)中的name=”third“時(shí),發(fā)現(xiàn)plane函數(shù)中并沒(méi)有name這個(gè)局部變量,恰好代碼又在ctrip這個(gè)大函數(shù)中,所以解析器就會(huì)回溯到ctrip函數(shù)中尋找name,發(fā)現(xiàn)果然有name,這個(gè)時(shí)候就把ctrip的name修改成了”third“。

又有一天,我喝多了酒又傻逼了一回,在定義plane函數(shù)的時(shí)候,把name="third" 錯(cuò)寫成了 nam="third"; 丟了一個(gè)e,你可以說(shuō)是酒精的問(wèn)題,

又不是我代碼的問(wèn)題。那么這個(gè)時(shí)候解析器該怎么處理呢?同樣的道理,在回溯時(shí),發(fā)現(xiàn)ctrip沒(méi)有,再回溯到頂層的window下,發(fā)現(xiàn)還是沒(méi)有,

這個(gè)時(shí)候解析器做了這樣的處理,既然整個(gè)鏈中都沒(méi)有,你又賦值了,我總不能給你報(bào)錯(cuò),那多尷尬呀,就索性給你在window下隱式的定義一個(gè)

nam變量,這個(gè)時(shí)候nam其實(shí)就是全局變量了。我們可以在window頂層console一下nam看看。

好了,關(guān)于變量的東西也就這么多了,沒(méi)什么稀奇的,理解了就沒(méi)什么意思了。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 汤原县| 莆田市| 南岸区| 红安县| 太白县| 巴林左旗| 鹿泉市| 福鼎市| 泾源县| 米林县| 凌云县| 舒城县| 华阴市| 渑池县| 杭州市| 皋兰县| 吴川市| 手机| 九龙城区| 雅安市| 长垣县| 濉溪县| 内江市| 岳西县| 镶黄旗| 历史| 新津县| 巩义市| 永胜县| 东台市| 晋中市| 平阳县| 中牟县| 屏山县| 长岭县| 吉林市| 惠来县| 深水埗区| 北京市| 中山市| 娄底市|