九色国产,午夜在线视频,新黄色网址,九九色综合,天天做夜夜做久久做狠狠,天天躁夜夜躁狠狠躁2021a,久久不卡一区二区三区

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
深入理解JavaScript作用域
JavaScript是門全棧性的語言,尤其是在2016年,經(jīng)常聽到JavaScript要一統(tǒng)天下的梗,甚至有流言說16年會個Vue.js就能找到工作,和當年iOS會個TableView就能找工作一樣.(tableView就相當于Android的ListView,不過現(xiàn)在基本都用RecyclerView了)
2016年前端的熱門技術(shù)基本都和JavaScript有關(guān),比如移動端跨平臺的Facebook出品的React Native和阿里的Weex,熱修復(fù)技術(shù)JSPath,以及后端的Node.js(本寶寶非常喜歡的一門技術(shù)棧).昨晚去gibhub看了下,Vue的star數(shù)量已經(jīng)超過了jQuery,雖然star數(shù)量并不能證明些什么,但是至少我們已經(jīng)看到,前端思想已經(jīng)從之前的document操作到了數(shù)據(jù)驅(qū)動開發(fā)的轉(zhuǎn)變(有興趣的話我可以之后結(jié)合Android、iOS、Vue,用一個小demo演示一下這個思想轉(zhuǎn)變),有些公司甚至開始嘗試用餓了么出品的Element來替代EasyUI(做過后端的同學(xué)應(yīng)該都知道EasyUI真的是AV畫質(zhì)....)
JS技術(shù)層出不窮,之前就有一篇很火的文章,2016年學(xué)JS是一種什么樣的體驗,瞬間嚇尿了不少人.大家都把注意力放到了框架和新技術(shù)上,原生的JS反而遭到了冷落,所以想通過幾個基礎(chǔ)性的JS問題,和大家一起交流(更希望大家?guī)绎w,但是別把我丟到馬航上飛...)
JavaScript中的作用域
下面一個簡單的問題:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<script>
var str1 = "hello";
var str2 = "world";
function t1() {
console.log(str1);
console.log(str2);
var str2 = "toby";
console.log(str2);
}
//這里會輸出什么?
t1();
</script>
這是一個很簡單的JS作用域問題,但是你越是強調(diào)簡單這兩個字,就越容易使人放松警惕,所以導(dǎo)致有些同學(xué)不假思索的回答輸出
● hello
● world
● toby
但是結(jié)果是輸出
● hello
● undefined
● toby
那么這就奇怪了,為什么會有undefined呢,不是應(yīng)該是world嗎?首先我們要明白,變量的尋找會遵循就近原則,所以js會先在函數(shù)中找,找不到才會向外找,而函數(shù)內(nèi)有str2,但是運行到console.log(str2)時str2未定義,所以就出現(xiàn)了undefined
詞法分析
知其然還必須其所以然,那么我們再來看幾個例子
例子1
1
2
3
4
5
6
7
8
9
10
<script>
function t(userName) {
console.log(www.dfza.info);//這里輸出什么?
function userName() {
console.log('tom');
}
}
t('toby');
</script>
輸出的結(jié)果是什么,這個例子好像和上面不一樣,有種回到高中數(shù)學(xué),題型一變就懵逼的感覺,這個時候可能有些同學(xué)會覺得是toby,但是實際輸出是
1
2
3
function userName() {
console.log('tom');
}
為什么是function呢?其實這種作用域的問題,都是可以通過"套公式"來得出,這個公式,就是JS中的詞法分析,JS中函數(shù)執(zhí)行前,必須要做的一項工作就是詞法分析,那么究竟要什么什么呢?分析參數(shù),分析變量聲明,分析函數(shù)聲明,那么我們就拿這道題來套一下公式
執(zhí)行t('toby')的時候,會開始兩個階段,一個是分析階段,分析完就到執(zhí)行階段
分析階段:
● 函數(shù)運行的瞬間,會生成一個Active Object對象(以下簡稱AO對象),一個函數(shù)作用域內(nèi)能找到的所有變量,都在AO上,此時用代碼表示為: t.AO = {}
● 分析參數(shù): 接收參數(shù),以參數(shù)名為屬性,參數(shù)值為屬性值,因為沒有參數(shù),因此分析結(jié)果用代碼表示為: t.AO = {userName : toby}
● 分析var聲明: t函數(shù)內(nèi)沒有var聲明,略過
● 分析函數(shù)聲明: 這個函數(shù)聲明有個特點,AO上如果有與函數(shù)名同名的屬性,則會被此函數(shù)覆蓋,因為函數(shù)在JS領(lǐng)域,也是變量的一種類型,因此用代碼表示為: t.AO = { userName : function userName() {console.log('tom');}}
執(zhí)行階段:
執(zhí)行t('toby')的時候,當執(zhí)行到console.log(userName)時,就調(diào)用t.AO.userName,所以,最后的輸出結(jié)果是function userName() {console.log('tom');}
例子2
1
2
3
4
5
6
7
8
9
10
<script>
function t(userName) {
console.log(userName);//這里輸出什么?
var userName = function () {
console.log('tom');
}
}
t('toby');
</script>
那這里的輸出又是什么呢?這個好像又和上面的例子不一樣,又再次陷入懵逼狀態(tài)?別怕麻煩,堅定的按照公式再走一次流程(上面的的例子寫得比較詳細,下面的分析就簡單寫)
分析之前,首先要弄明白兩個概念,一個叫函數(shù)聲明,一個叫函數(shù)表達式
1
2
3
4
5
6
7
8
9
//這個叫函數(shù)聲明
function userName() {
console.log('tom');
}
//這個叫函數(shù)表達式
var userName = function () {
console.log('tom');
}
分析階段:
● 創(chuàng)建AO對象,t.AO = {}
● 分析參數(shù): t.AO = {userName : toby}
● 分析var聲明: 在AO上,形成一個屬性,以var的變量名為屬性名,值為undefined,(因為是先分析,后執(zhí)行,這只是詞法分析階段,并不是執(zhí)行階段,分析階段值都是undefined,如果執(zhí)行階段有賦值操作,那值會按照正常賦值改變),也就是說代碼應(yīng)該表示為:t.AO = {userName : undefined},但是還有另外一個原則,那就是如果AO有已經(jīng)有同名屬性,則不影響(也就是什么事都不做),由于分析參數(shù)時,AO上已經(jīng)有userName這個屬性了,所以按照這個原則,此時什么事都不做,也就是說,此時按照分析參數(shù)時的結(jié)果t.AO = {userName : toby}
● 分析函數(shù)聲明: 此時沒有函數(shù)聲明,略過
執(zhí)行階段:
調(diào)用t.AO.userName,所以,最后的輸出結(jié)果是toby
例子3
1
2
3
4
5
6
7
8
9
10
11
12
<script>
t();
t2();
function t() {
console.log('toby');//這里會輸出什么?
}
var t2 = function () {
console.log('hello toby');//這里會輸出什么?
};
</script>
那么我們再來看一個例子,這下徹底回到高中時代,做了兩個例子好像感覺掌握了,結(jié)果考試你給來看這個?
答案是,t()輸出為toby,t2()則會報錯.這又是為什么?
● t()可以調(diào)用是因為在詞法分析的過程,就已經(jīng)完成了t函數(shù)的分析,所以可以調(diào)用
● t2()不能調(diào)用是因為在詞法分析的階段,分析到有一個t2聲明,在AO上只是形成了一個屬性,但是值為undefined
例子4
1
2
3
4
5
6
7
8
9
10
<script>
function t(userName) {
console.log(userName);//這里輸出什么?
function userName() {
console.log(userName);//這里輸出什么?
}
userName();
}
t('toby');
</script>
函數(shù)里面套函數(shù),這次竟然又和前面不一樣了...這次我不說答案了,直接先套公式走一波
t('toby')的分析和執(zhí)行階段
分析階段:
● 創(chuàng)建AO對象,t.AO = {}
● 分析參數(shù): t.AO = {userName : toby}
● 分析var聲明: 有同名屬性,不做任何事,還是t.AO = {userName : toby}
● 分析函數(shù)聲明: 有同名屬性,覆蓋: t.AO = {userName : function userName() {console.log(userName);}}
執(zhí)行階段: t.AO.userName 輸出為function userName() {console.log(userName);}}
userName()的分析和執(zhí)行階段
這里也要搞清楚兩個概念
1
2
3
4
5
6
7
8
9
//執(zhí)行userName()分析的是
function () {
console.log(userName);
};
//而不是
var userName = function () {
console.log(userName);
};
分析階段:
● 創(chuàng)建AO對象,userName.AO = {}
● 分析參數(shù): 無,略過
● 分析var聲明: 無,略過
● 分析函數(shù)聲明: 無,略過
執(zhí)行階段: 因為此時userName.AO = {}是個空對象,無法執(zhí)行userName.AO.userName,所以會向上一層找,所以輸出t.AO.userName的結(jié)果,也就是function userName() {console.log(userName);}}
例子5
1
2
3
4
5
6
7
8
9
10
<script>
function t(www.7aqp.com) {
console.log(userName);//這里輸出什么?
var userName = function () {
console.log(userName);//這里輸出什么?
}
userName();
}
t('toby');
</script>
好吧,我保證這個是最后一道...這個輸出結(jié)果是什么呢?我們只要堅定公式?jīng)]問題,就一定能得出結(jié)果,那么再套公式走一波
t('toby')的分析和執(zhí)行階段
分析階段:
● 創(chuàng)建AO對象,t.AO = {}
● 分析參數(shù): t.AO = {userName : toby}
● 分析var聲明: 有同名屬性,不做任何事,還是t.AO = {userName : toby}
● 分析函數(shù)聲明: 無,略過
執(zhí)行階段: 執(zhí)行console.log(userName);時調(diào)用t.AO.userName 輸出為toby,執(zhí)行完后,代碼繼續(xù)往下執(zhí)行,那么就到了進行var的賦值操作(var的分析和執(zhí)行的區(qū)別看例子2中我有解釋),此時t.AO = {userName : function userName() {console.log(userName);}}},代碼繼續(xù)往下執(zhí)行,接著就執(zhí)行到了userName()
userName()的分析和執(zhí)行階段
分析階段:
● 創(chuàng)建AO對象,userName.AO = {}
● 分析參數(shù): 無,略過
● 分析var聲明: 無,略過
● 分析函數(shù)聲明: 無,略過
執(zhí)行階段: 按照例子4我們知道userName.AO是個空對象,所以會往上調(diào)用t.AO.userName,所以輸出為:function userName() {console.log(userName);}}}
總結(jié)
JavaScript作用域會先在自己的AO上找,找不到就到父函數(shù)的AO上找,再找不到再找上一層的AO,直到找到window.這樣就形成一條鏈,這條AO鏈就是JavaScript中的作用域鏈.JavaScript中有兩條很重要的鏈,一條是作用域鏈,一條是原型鏈,
本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
前端基礎(chǔ)進階(三):變量對象詳解
預(yù)編譯與作用域鏈
JavaScript中的預(yù)編譯如何進行
JavaScript 預(yù)編譯與作用域
什么是匿名函數(shù)?
js自執(zhí)行函數(shù)
更多類似文章 >>
生活服務(wù)
熱點新聞
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服