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