前端總結(jié)js基礎(chǔ)原理昼牛,js執(zhí)行過(guò)程理解

一泛鸟,數(shù)據(jù)類(lèi)型

1蝠咆,基本數(shù)據(jù)類(lèi)型(值類(lèi)型):

number,string谈况,boolean勺美,null,undefined碑韵。

2,引用數(shù)據(jù)類(lèi)型:

對(duì)象缎脾,數(shù)組祝闻,函數(shù)。

如:{ }遗菠,[ ]联喘, 日期對(duì)象new Date(), Math辙纬,實(shí)例對(duì)象...

3豁遭,ES6中新增,Symbol(唯一值)

4贺拣,ES11(ES2020)新增蓖谢,bigInt(一種方法來(lái)表示大于 2?3-1 的整數(shù)捂蕴,BigInt 可用于任意大整數(shù))。

例如:let a = Symbol('1')

? ? ? ? ? let b = Symbol('1')

? ? ? ? ? a != b? // true

另:NaN == NaN? // false闪幽,NaN和誰(shuí)都不相等啥辨。

二,變量

創(chuàng)建一個(gè)變量會(huì)有三步操作

例如:let a = 1

1盯腌,創(chuàng)建變量:聲明 let a

2溉知,創(chuàng)建值: 基本值直接在棧中創(chuàng)建和存儲(chǔ)? 1

3,讓變量和值關(guān)聯(lián)起來(lái)(賦值):定義 defined腕够。當(dāng)然未賦值是undefined(ps:終于知道undefined怎么來(lái)的了)级乍。

在第2步中,當(dāng)引用值是復(fù)雜的結(jié)構(gòu)時(shí)特殊處理帚湘。

如:let obj = { a: 1 }

function Fn(){ let a = 1 }

(ps:函數(shù)也是變量卡者,和let創(chuàng)建的變量本質(zhì)上是一樣的,區(qū)別是存儲(chǔ)的值是個(gè)函數(shù)類(lèi)型的值客们。)

1崇决,開(kāi)辟一個(gè)存儲(chǔ)對(duì)象中鍵值對(duì)(存儲(chǔ)函數(shù)中的代碼)的內(nèi)存空間“堆內(nèi)存”。

2底挫,所有的堆內(nèi)存都有一個(gè)可被后續(xù)查找的16進(jìn)制地址恒傻。

3,后續(xù)關(guān)聯(lián)賦值的時(shí)候建邓,是把堆內(nèi)存地址給與變量操作盈厘。

如下圖所示存儲(chǔ):

圖二

問(wèn)題:

1,let 和 var的區(qū)別官边?

let 語(yǔ)句創(chuàng)建了自己的作用域沸手,這個(gè)作用域里的變量與外面的變量無(wú)關(guān)。

圖1-1
圖1-2

2注簿,變量提升是怎么回事契吉?

JavaScript會(huì)把作用域里的所有變量和函數(shù)提到函數(shù)的頂部聲明,帶著這個(gè)原理看以下的例子诡渴。

圖2-1

上圖中的值是undefined說(shuō)明變量已經(jīng)提前聲明捐晶,只是沒(méi)有被賦值。由此解釋?zhuān)兞刻嵘傅氖亲兞柯暶鞯奶嵘纾粫?huì)提升變量的初始化和賦值惑灵。

let的情況不同:

圖2-2

瀏覽器認(rèn)為c沒(méi)有聲明,是否意味著沒(méi)有變量提升呢眼耀?再看一個(gè)例子英支,

圖2-3

這里同樣認(rèn)為c沒(méi)有聲明,但是哮伟,如果c沒(méi)有變量提升干花,執(zhí)行到console.log時(shí)應(yīng)該是輸出全局作用域中的c妄帘,而不是出現(xiàn)錯(cuò)誤。

可以推知let也出現(xiàn)了變量提升把敢。出現(xiàn)這種情況我們稱(chēng)為“暫時(shí)性死區(qū)”(temporal dead zone寄摆,簡(jiǎn)稱(chēng) TDZ),在代碼塊內(nèi)修赞,使用let婶恼、const命令聲明變量之前,該變量都是不可用的柏副。

3勾邦,函數(shù)會(huì)被優(yōu)先提升到上面

圖2-4

4,語(yǔ)句塊是沒(méi)有局部作用域的割择,在下面的語(yǔ)句塊中眷篇,與外部是完全一致的。if里面的變量和函數(shù)也會(huì)被提升到函數(shù)頂部

圖2-5

三荔泳,js引擎是怎么執(zhí)行代碼的

js引擎想要執(zhí)行代碼蕉饼,一定會(huì)創(chuàng)建一個(gè)執(zhí)行棧ECStack(執(zhí)行上下文環(huán)境棧)。

棧內(nèi)存玛歌,我們簡(jiǎn)單的理解為執(zhí)行代碼所用昧港,那么函數(shù)執(zhí)行就是個(gè)進(jìn)棧和出棧的過(guò)程。

步驟如下:

1支子,把創(chuàng)建的上下文壓縮到棧中執(zhí)行 => 進(jìn)棧

2创肥,執(zhí)行完有的上下文就沒(méi)用了 => 出棧

3,有的還要用值朋,會(huì)把它壓縮到棧底 => 閉包

我們執(zhí)行下面函數(shù)分析其過(guò)程:

圖 三

四叹侄,閉包的理解

《JavaScript高級(jí)程序設(shè)計(jì)》里面對(duì)閉包的定義是,閉包是指有權(quán)訪問(wèn)另一個(gè)函數(shù)作用域中的變量的函數(shù)昨登。對(duì)定義中的另一個(gè)函數(shù)作用域理解可能有點(diǎn)模糊趾代。

而上面三中簡(jiǎn)單的說(shuō)了下當(dāng)函數(shù)進(jìn)棧執(zhí)行后,還要用到該函數(shù)不能出棧篙骡,就形成閉包稽坤。結(jié)合《JavaScript高級(jí)程序設(shè)計(jì)》分析閉包,如圖:

圖四

五糯俗,關(guān)于作用域

創(chuàng)建一個(gè)函數(shù)的時(shí)候,會(huì)創(chuàng)建一個(gè)堆睦擂,存儲(chǔ)代碼字符串和對(duì)應(yīng)的鍵值對(duì)得湘,初始化當(dāng)前函數(shù)的作用域[[scope]] = 所在上下文EC中的變量對(duì)象VO/AO。

執(zhí)行函數(shù)的時(shí)候顿仇,會(huì)創(chuàng)建一個(gè)新的執(zhí)行上下文EC淘正,初始化this的指向摆马,初始化作用域鏈[[scopeChain]]:<AO(A), VO(G)>,創(chuàng)建AO變量對(duì)象來(lái)存儲(chǔ)變量鸿吆。(對(duì)比上圖四)

六囤采,this執(zhí)行主體的簡(jiǎn)單判斷

第一種,函數(shù)執(zhí)行惩淳,看前面是否有“點(diǎn)”蕉毯,有點(diǎn)前面是誰(shuí)this就是誰(shuí) 如:obj.fn()? ?this->obj, obj._proto_.fn? this->obj._proto

沒(méi)有點(diǎn)思犁,this是window(嚴(yán)格模式下是undefined)? 相當(dāng)window.fn()? ?this->window

自執(zhí)行函數(shù)一般this都是window代虾。

第二種,給元素的事件行為綁定方法(DOM0/DOM2)激蹲,事件觸發(fā)棉磨,方法會(huì)執(zhí)行,此時(shí)方法中的this一般都是當(dāng)前元素本身学辱,如:

? box.onclick = function() {

this-> box

? }

? box.addEventListener("click", function(){

this->box

? })

七乘瓤,原型和原型鏈

原型(prototype),每個(gè)函數(shù)都有一個(gè)prototype屬性策泣,他默認(rèn)指向一個(gè)Object空對(duì)象衙傀,原形對(duì)象有個(gè)constructor, 他指向函數(shù)對(duì)象着降。

我們給原型對(duì)象添加屬性(一般是方法)時(shí)差油,函數(shù)的所有實(shí)例對(duì)象會(huì)自動(dòng)擁有原型中的屬性。

例如:

function A() {}? ? //? 內(nèi)部語(yǔ)句:this.prototype = {}

A.prototype.test= function() {

? console.log(test)

}

let a? = new A()? //? 內(nèi)部語(yǔ)句:this(fn).__proto__ = Fn.prototype

a.test()? // test

原型有顯式原型和隱式原型任洞。

每個(gè)函數(shù)都有個(gè)prototype蓄喇,即顯示原型。在定義函數(shù)時(shí)自動(dòng)添加交掏,默認(rèn)值是一個(gè)空Object對(duì)象妆偏。

每個(gè)實(shí)例對(duì)象都有一個(gè)__proto__,稱(chēng)隱式原型盅弛。在創(chuàng)建對(duì)象時(shí)自動(dòng)添加钱骂,默認(rèn)值是構(gòu)造函數(shù)的prototype屬性。函數(shù)也是對(duì)象挪鹏,故也創(chuàng)建了__proto__见秽,下圖所示

對(duì)象的隱式原型的值為其對(duì)應(yīng)構(gòu)造函數(shù)的顯示原型的值,fn.__proto__ === Fn.prototype

在ES6之前讨盒,可以直接操作顯式原型解取,但不能直接操作隱式原型。

圖七

原型鏈返顺,訪問(wèn)一個(gè)對(duì)象時(shí)禀苦,先在自身屬性中查找蔓肯,找到返回。如果沒(méi)找到振乏,沿__proto__這條鏈向上查找蔗包,找到返回。如果最終沒(méi)找到慧邮,返回undefined调限。所以別名又叫隱式原型鏈 。

作用:查找對(duì)象的屬性和方法(備注:讀取對(duì)象屬性值是赋咽,會(huì)自動(dòng)查找原型鏈旧噪;如果是設(shè)置對(duì)象屬性時(shí),不會(huì)查找原型鏈)

我們執(zhí)行下面函數(shù)分析其查找過(guò)程:(備注:創(chuàng)建對(duì)象 let obj = {}相當(dāng) new Object()脓匿,function Fn(){}相當(dāng) Fn = new Function() )


圖七-1

理解上圖查找后可以對(duì)照下面的原型鏈萬(wàn)能表加深理解:

圖七-2

八淘钟,js事件循環(huán)

先引進(jìn)概念:

1,js是單線程的陪毡,也就是說(shuō)米母,同一個(gè)時(shí)間只能做一件事。(ps:為啥是單線程毡琉?假定JavaScript同時(shí)有兩個(gè)線程铁瞒,一個(gè)線程在某個(gè)DOM節(jié)點(diǎn)上添加內(nèi)容,另一個(gè)線程刪除了這個(gè)節(jié)點(diǎn)桅滋,這時(shí)瀏覽器應(yīng)該以哪個(gè)線程為準(zhǔn))慧耍。

2,瀏覽器是多線程的:

瀏覽器多線程

3丐谋,setTimeout的執(zhí)行:setTimeout在棧中執(zhí)行后觸發(fā)瀏覽器的定時(shí)觸發(fā)器線程芍碧,定時(shí)器觸發(fā)線程倒計(jì)時(shí)在setTimeout設(shè)置的時(shí)間(如300ms)后把回調(diào)函數(shù)里面的數(shù)據(jù)加到消息隊(duì)列中。

4号俐,回調(diào)函數(shù)的執(zhí)行:回調(diào)函數(shù)會(huì)加到微任務(wù)隊(duì)列中等待執(zhí)行泌豆。如:promise執(zhí)行后會(huì)把then的回調(diào)函數(shù)加到微任務(wù)隊(duì)列中。

5吏饿,先執(zhí)行宏任務(wù)踪危,在執(zhí)行微任務(wù)隊(duì)列,最后執(zhí)行消息隊(duì)列猪落。

js事件循環(huán)機(jī)制解決單線程阻塞問(wèn)題贞远。那js是怎么處理異步(setTimeout)和回調(diào)函數(shù)(promise.then(()=>{...}))的呢?以下面代碼例子:


圖八


笨忌。兴革。。如理解有誤望指點(diǎn)學(xué)習(xí)蜜唾。

作用域參考文章:https://cloud.tencent.com/developer/article/1196843

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末杂曲,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子袁余,更是在濱河造成了極大的恐慌擎勘,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,968評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件颖榜,死亡現(xiàn)場(chǎng)離奇詭異棚饵,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)掩完,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)噪漾,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人且蓬,你說(shuō)我怎么就攤上這事欣硼。” “怎么了恶阴?”我有些...
    開(kāi)封第一講書(shū)人閱讀 153,220評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵诈胜,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我冯事,道長(zhǎng)焦匈,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,416評(píng)論 1 279
  • 正文 為了忘掉前任昵仅,我火速辦了婚禮缓熟,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘摔笤。我一直安慰自己够滑,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布籍茧。 她就那樣靜靜地躺著版述,像睡著了一般。 火紅的嫁衣襯著肌膚如雪寞冯。 梳的紋絲不亂的頭發(fā)上渴析,一...
    開(kāi)封第一講書(shū)人閱讀 49,144評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音吮龄,去河邊找鬼俭茧。 笑死,一個(gè)胖子當(dāng)著我的面吹牛漓帚,可吹牛的內(nèi)容都是我干的母债。 我是一名探鬼主播,決...
    沈念sama閱讀 38,432評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼毡们!你這毒婦竟也來(lái)了迅皇?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,088評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤衙熔,失蹤者是張志新(化名)和其女友劉穎登颓,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體红氯,經(jīng)...
    沈念sama閱讀 43,586評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡框咙,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了痢甘。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片喇嘱。...
    茶點(diǎn)故事閱讀 38,137評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖塞栅,靈堂內(nèi)的尸體忽然破棺而出者铜,到底是詐尸還是另有隱情,我是刑警寧澤构蹬,帶...
    沈念sama閱讀 33,783評(píng)論 4 324
  • 正文 年R本政府宣布王暗,位于F島的核電站,受9級(jí)特大地震影響庄敛,放射性物質(zhì)發(fā)生泄漏俗壹。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評(píng)論 3 307
  • 文/蒙蒙 一藻烤、第九天 我趴在偏房一處隱蔽的房頂上張望绷雏。 院中可真熱鬧,春花似錦怖亭、人聲如沸涎显。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,333評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)期吓。三九已至,卻和暖如春倾芝,著一層夾襖步出監(jiān)牢的瞬間讨勤,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,559評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工晨另, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留潭千,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,595評(píng)論 2 355
  • 正文 我出身青樓借尿,卻偏偏與公主長(zhǎng)得像刨晴,于是被迫代替她去往敵國(guó)和親屉来。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容