摘要:變量對(duì)象實(shí)際上是一個(gè)邏輯上的概念,是邏輯上作用域鏈的組成元素。在全局上下文中,全局對(duì)象充當(dāng)變量對(duì)象,全局上下文的作用域鏈中存放全局對(duì)象在函數(shù)進(jìn)入執(zhí)行上下文之前,會(huì)生成一個(gè)活動(dòng)對(duì)象,將參數(shù)函數(shù)聲明變量聲明按這個(gè)順序添加到變量對(duì)象之中。
javascript的執(zhí)行過程
整個(gè)JavaScript的代碼運(yùn)行可以分為 <建立執(zhí)行上下文> 和 <代碼執(zhí)行> 兩個(gè)階段;
其中執(zhí)行上下文的建立包括:
初始化this
變量對(duì)象VO(活動(dòng)對(duì)象AO)
作用域鏈SC;
代碼執(zhí)行時(shí)會(huì)實(shí)例化VO或AO對(duì)象中的變量;具體如下:
執(zhí)行上下文 execution context執(zhí)行上下文會(huì)有三種情況:
全局執(zhí)行上下文、
函數(shù)執(zhí)行上下文、
eval執(zhí)行上下文;
引擎會(huì)在執(zhí)行時(shí)建立執(zhí)行上下文堆棧;執(zhí)行上下文會(huì)初始化三個(gè)對(duì)象:this、變量對(duì)象VO/活動(dòng)對(duì)象AO、作用域鏈。
this對(duì)象使用easy模式來判定this的指向,作為對(duì)象屬性方法調(diào)用時(shí)指向?qū)ο?,作為全局方法使用指向window,函數(shù)中的this主要是依賴于調(diào)用者,在進(jìn)行賦值等操作時(shí)注意this的指向丟失問題;
變量對(duì)象VO/激活對(duì)象AO看有些資料說變量對(duì)象和活動(dòng)對(duì)象是一回事兒,甚至有些資料說其差異在于活動(dòng)對(duì)象多了arguments屬性。昨天的學(xué)習(xí)課程讓我對(duì)這個(gè)問題有了清晰的認(rèn)識(shí)。變量對(duì)象實(shí)際上是一個(gè)邏輯上的概念,是邏輯上作用域鏈的組成元素。而在實(shí)際的實(shí)踐中則大部分時(shí)間由活動(dòng)對(duì)象充當(dāng)這個(gè)角色。在全局上下文中,全局對(duì)象window充當(dāng)變量對(duì)象,全局上下文的作用域鏈中存放全局對(duì)象;在函數(shù)進(jìn)入執(zhí)行上下文之前,會(huì)生成一個(gè)活動(dòng)對(duì)象,將arguments、參數(shù)、函數(shù)聲明、變量聲明按這個(gè)順序添加到變量對(duì)象之中。
在VO/AO中存在同名變量時(shí)的覆蓋順序是:應(yīng)該是函數(shù)聲明>函數(shù)形參>變量;也就是在這里完成變量聲明、函數(shù)形參和函數(shù)聲明的提前的;而變量聲明不會(huì)進(jìn)行復(fù)制操作,函數(shù)形參也沒有復(fù)制操作一說;需要注意的是函數(shù)聲明會(huì)把函數(shù)體帶入,此時(shí)函數(shù)會(huì)建立相應(yīng)的隱式[[scope]]數(shù)組屬性,這個(gè)數(shù)組指向的當(dāng)前上下文的作用域鏈,需要注意的是這里只有函數(shù)聲明,不會(huì)有函數(shù)表達(dá)式,函數(shù)聲明都是在跟語句下,而函數(shù)表達(dá)式都是在執(zhí)行代碼時(shí)建立的;
函數(shù)中的激活對(duì)象最開始只有一個(gè)對(duì)象;就是arguments這個(gè)對(duì)象,有著length、callee等屬性;
其實(shí)VO/AO都是作為當(dāng)前上下文的作用于鏈的組成元素,
作用域鏈scope chain全局執(zhí)行上下文的作用域鏈就是[window];
函數(shù)的作用域鏈就是 [當(dāng)前上下文的VO/AO,自身的scope內(nèi)容];這里函數(shù)的隱式[[scope]]是在函數(shù)被聲明或者被表達(dá)式執(zhí)行時(shí)建立的,也就是上文說的當(dāng)前執(zhí)行上下文的作用域鏈;
變量實(shí)例化在代碼執(zhí)行前,上下文建立后來完成的
原型所有的對(duì)象都是通過函數(shù)創(chuàng)建的,首先看看函數(shù)和new操作時(shí)都發(fā)生了什么:其中隱式[[prototype]]也就是瀏覽器中認(rèn)為的 _protp_這個(gè)對(duì)象
prototype原型函數(shù)也是一種對(duì)象。他也是屬性的集合,你也可以對(duì)函數(shù)進(jìn)行自定義屬性。javascript自己就默認(rèn)的給函數(shù)一個(gè)屬性------prototype。對(duì),每個(gè)函數(shù)都有一個(gè)屬性叫做prototype。這個(gè)prototype的屬性值是一個(gè)對(duì)象(屬性的集合,再次強(qiáng)調(diào)?。?,默認(rèn)的只有一個(gè)叫做constructor的屬性,指向這個(gè)函數(shù)本身。
進(jìn)行new Object()時(shí)的情況
隱式原型"_proto_"也是[[prototype]]
每個(gè)函數(shù)function都有一個(gè)prototype,即原型。這里再加一句話------每個(gè)對(duì)象都有一個(gè)_proto_,可成為隱式原型。這個(gè)_proto_是一個(gè)隱藏的屬性,javascript不希望開發(fā)者用到這個(gè)屬性值,有的低版本瀏覽器甚至不支持這個(gè)屬性值。
每個(gè)對(duì)象都有一個(gè)_proto_屬性,指向創(chuàng)建該對(duì)象的函數(shù)的prototype。
同樣自定義函數(shù)的prototype。自定義函數(shù)的prototype本質(zhì)上就是和 var obj = {} 是一樣的,都是被Object創(chuàng)建,所以它的_proto_指向的就是Object.prototype。
但是Object.prototype確實(shí)一個(gè)特例------它的_proto_指向的是null,切記切記!
同樣之前說了函數(shù)也是對(duì)象,那么函數(shù)的_proto_是誰?是Function.prototype,而Function.prototype指向的對(duì)象也是對(duì)象,它的_proto_是不是也指向Object.prototype?看一張大圖慢慢理解:
其實(shí)在JavaScript中的instanceof就是跟著原型鏈這么來進(jìn)行判定的;
創(chuàng)建function算法 函數(shù)有prototype屬性是個(gè)對(duì)象和[[Prototype]]也就是_proto_屬性
F=new Object();創(chuàng)建對(duì)象 F.[[class]]="Function";指定類型 F.[[Prototype]]=Function.prototype;把_proto_指向函數(shù)的prototype F.[[Call]]=internalCall; 內(nèi)部調(diào)用 F.[[Construct]]=internalConstructor; 內(nèi)部構(gòu)造 F.[[Scope]]=currentContext.Scope Chain.concat(); 把[[Scope]]是當(dāng)前執(zhí)行上下文作用域 F.length=FormalParameterNum //DontDelete ReadOnly DontEnum temp=new Object(); 初始化prototype temp.constructor=F; 初始化prototype下的constructor //DontEnum DontDelete F.prototype=temp; 完成初始化 return F 返回
new函數(shù)
function internalConstructor(parameters){ O=new Object(); O.[[Class]]="Object"; O.[[Prototype]]=Object.prototype; R=F.[[Call]].apply(O,parameters); return O; }
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/87072.html
摘要:引擎是能運(yùn)行代碼的程序或解釋器。代碼的運(yùn)行明顯的分成兩個(gè)階段,也就是編譯階段和運(yùn)行字節(jié)碼階段。它首先由編譯器編譯成字節(jié)碼文件,然后再通過虛擬機(jī)從文件中讀一行解釋執(zhí)行一行。 Javascript引擎是能運(yùn)行javascript代碼的程序或解釋器。做為前端開發(fā)人員,了解javascript底層的工作原理,可以用助于寫出高效的javascript代碼。那我們就來看一下,我們寫的代碼是如何在j...
摘要:異步任務(wù)必須指定回調(diào)函數(shù),當(dāng)異步任務(wù)從任務(wù)隊(duì)列回到執(zhí)行棧,回調(diào)函數(shù)就會(huì)執(zhí)行。事件循環(huán)主線程從任務(wù)隊(duì)列中讀取事件,這個(gè)過程是循環(huán)不斷的,所以整個(gè)的這種運(yùn)行機(jī)制又稱為。事件循環(huán)事件循環(huán)是指主線程重復(fù)從消息隊(duì)列中取消息執(zhí)行的過程。 參考鏈接:這一次,徹底弄懂 JavaScript 執(zhí)行機(jī)制https://zhuanlan.zhihu.com/p/...從瀏覽器多進(jìn)程到JS單線程,JS運(yùn)行機(jī)制...
摘要:在瀏覽區(qū)中的性能,可以認(rèn)為是開發(fā)者所面臨的最嚴(yán)重的可用性問題。優(yōu)化這個(gè)問題的第一步從它的加載和執(zhí)行開始。這意味著在對(duì)象的事件觸發(fā)后再下載腳本。屬性指明本元素所含的腳本不會(huì)修改,因此代碼能夠安全地執(zhí)行,但是瀏覽器的支持情況不理想。 JavaScript在瀏覽區(qū)中的性能,可以認(rèn)為是開發(fā)者所面臨的最嚴(yán)重的可用性問題。 優(yōu)化這個(gè)問題的第一步從它的加載和執(zhí)行開始。 霸道的script標(biāo)簽scr...
摘要:回調(diào)函數(shù),一般在同步情境下是最后執(zhí)行的,而在異步情境下有可能不執(zhí)行,因?yàn)槭录]有被觸發(fā)或者條件不滿足。同步方式請(qǐng)求異步同步請(qǐng)求當(dāng)請(qǐng)求開始發(fā)送時(shí),瀏覽器事件線程通知主線程,讓線程發(fā)送數(shù)據(jù)請(qǐng)求,主線程收到 一直以來都知道JavaScript是一門單線程語言,在筆試過程中不斷的遇到一些輸出結(jié)果的問題,考量的是對(duì)異步編程掌握情況。一般被問到異步的時(shí)候腦子里第一反應(yīng)就是Ajax,setTimse...
摘要:下面我們撇開網(wǎng)絡(luò)方面的優(yōu)化,只分析靜態(tài)資源方面的優(yōu)化。不過,也會(huì)阻止的構(gòu)建和延緩網(wǎng)頁(yè)渲染。未優(yōu)化正常加載優(yōu)化后異步加載根據(jù)上面的分析,我們可以清楚的認(rèn)識(shí)到,非必要優(yōu)先加載的,選擇異步加載是最優(yōu)選擇。 為什么做優(yōu)化 經(jīng)典問題:白屏?xí)r間過長(zhǎng),用戶體驗(yàn)差產(chǎn)生的原因:網(wǎng)絡(luò)問題、關(guān)鍵渲染路徑(CRP)問題 怎么做優(yōu)化 如何做好優(yōu)化呢,網(wǎng)上隨便一搜,就有很多優(yōu)化總結(jié),無非就是網(wǎng)絡(luò)優(yōu)化、靜態(tài)資源(h...
摘要:下面我們撇開網(wǎng)絡(luò)方面的優(yōu)化,只分析靜態(tài)資源方面的優(yōu)化。不過,也會(huì)阻止的構(gòu)建和延緩網(wǎng)頁(yè)渲染。未優(yōu)化正常加載優(yōu)化后異步加載根據(jù)上面的分析,我們可以清楚的認(rèn)識(shí)到,非必要優(yōu)先加載的,選擇異步加載是最優(yōu)選擇。 為什么做優(yōu)化 經(jīng)典問題:白屏?xí)r間過長(zhǎng),用戶體驗(yàn)差產(chǎn)生的原因:網(wǎng)絡(luò)問題、關(guān)鍵渲染路徑(CRP)問題 怎么做優(yōu)化 如何做好優(yōu)化呢,網(wǎng)上隨便一搜,就有很多優(yōu)化總結(jié),無非就是網(wǎng)絡(luò)優(yōu)化、靜態(tài)資源(h...
閱讀 756·2021-09-30 09:47
閱讀 2947·2021-09-04 16:40
閱讀 924·2019-08-30 13:18
閱讀 3504·2019-08-29 16:22
閱讀 1629·2019-08-29 12:36
閱讀 671·2019-08-29 11:11
閱讀 1530·2019-08-26 13:47
閱讀 1191·2019-08-26 13:32