




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1、紅色虛線表示隱式Prototype鏈。這張對象模型圖中包含了太多東西,不少地方需要仔細體會,可以寫些測試代碼進行驗證。徹底理解了這張圖,對JavaScript語言的了解也就差不多了。下面是一些補充說明:1. 圖中有好幾個地方提到build-in Function constructor,這是同一個對象,可以測試驗證:/PassedinFF2.0,IE7,Opera9.25,Safari3.0.4Function=Function.constructor/result:trueFunction=Ftotype.constructor/result:trueFunction=
2、Object.constructor/result:true/FunctionalsoequalstoNumber.constructor,String.constructor,Array.constructor,RegExp.constructor,etc.functionfn()Function=fn.constructor/result:true這說明了幾個問題: Function指向系統(tǒng)內(nèi)置的函數(shù)構(gòu)造器(build-in Function constructor);Function具有自舉性;系統(tǒng)中所有函數(shù)都是由Function構(gòu)造。2. 左下角的obj1, obj2.objn范指用類
3、似這樣的代碼創(chuàng)建的對象: function fn1(); var obj1=new fn1(); 這些對象沒有本地constructor方法,但它們將從Prototype鏈上得到一個繼承的constructor方法,即totype.constructor,從函數(shù)對象的構(gòu)造過程可以知道,它就是fn本身了。 右下角的obj1, obj2.objn范指用類似這樣的代碼創(chuàng)建的對象: var obj1=new Object();或var obj1=;或var obj1=new Number(123);或obj1=/w+/;等等。所以這些對象Prototype鏈的指向、從Prototype鏈繼
4、承而來的 constructor的值(指它們的constructor是build-in Number constructor還是build-in Object constructor等)等依賴于具體的對象類型。另外注意的是,var obj=new Object(123);這樣創(chuàng)建的對象,它的類型仍然是Number,即同樣需要根據(jù)參數(shù)值的類型來確定。 同樣它們也沒有本地constructor,而是從Prototype鏈上獲得繼承的constructor方法,即build-in * constructor,具體是哪一個由數(shù)據(jù)類型確定。3. 關(guān)于圖中Prototype鏈的補充說明:Object.pr
5、ototype是整個鏈的終結(jié)點,它的內(nèi)部Prototype為null。所有函數(shù)的Prototype鏈都指向Ftotype。Function的Prototype鏈指向Ftotype,這是規(guī)范要求的,因為設(shè)計者將Function設(shè)計為具有自舉性。 Function的Prototype鏈這樣設(shè)計之后,F(xiàn)unction.constructor=Function, Function instanceOf Function都為true。另外Function已經(jīng)是最頂層的構(gòu)造器,但Function本身也是一個函數(shù)對象,它必然是由某個東西創(chuàng)建出來的,這 樣自舉在語義
6、上合情合理。Ftotype的Prototype鏈指向Ototype,這也是規(guī)范強制要求的。首先 Ftotype是Function的一個實例對象(typeof Ftotype可以知道它是一個Function,instanceOf無法通過測試,因為Prototype鏈在內(nèi)部被額外設(shè)置 了),所以按照Prototype的規(guī)則,F(xiàn)totype的內(nèi)部Prototype值應(yīng)當為 Ftotype這個對象,即它的Prototype鏈指向自己本身。這樣一方面在Prototype鏈上造成
7、一個死循環(huán),另一方面 它本身成為了一個終結(jié)點,結(jié)果就是所有函數(shù)對象將不是派生自O(shè)bject了。加上這個強制要求之后,Prototype鏈只有唯一的一個終結(jié)點。4. 因為Ftotype是一個函數(shù)對象,所以它應(yīng)當具有顯示的prototype屬性,即 Ftotype,但只有FireFox中可以訪問到,IE、Opera、Safari都無法訪問。所以圖中用 了個表示不存在的符號。5. 用戶自定義函數(shù)(user defined functions)默認情況下Prototype值是Ototype,即它的隱式Prototype鏈
8、指向 Ototype,所以圖中就這樣表示了,但并不代表總是這樣,當用戶設(shè)置了自定義函數(shù)的prototype屬性之后,情況就不同了。執(zhí)行模型執(zhí)行上下文(Execution Context)簡介JavaScript代碼運行的地方都存在執(zhí)行上下文,它是一個概念,一種機制,用來完成JavaScript運行時作用域、生存期等方面的處理。執(zhí)行上 下文包括Variable Object、Variable Instatiation、Scope/Scope Chain等概念,在不同的場景/執(zhí)行環(huán)境下,處理上存在一些差異,下面先對這些場景進行說明。函數(shù)對象分為用戶自定義函數(shù)對象和系統(tǒng)內(nèi)置函數(shù)對象
9、,對于用戶自定義函數(shù)對象將按照下面描述的機制進行處理,但內(nèi)置函數(shù)對象與具體實現(xiàn)相關(guān),ECMA規(guī)范對它們執(zhí)行上下文的處理沒有要求,即它們基本不適合本節(jié)描述的內(nèi)容。執(zhí)行的JavaScript代碼分三種類型,后面會對這三種類型處理上不同的地方進行說明:1. Global Code,即全局的、不在任何函數(shù)里面的代碼,例如一個js文件、嵌入在HTML頁面中的js代碼等。2. Eval Code,即使用eval()函數(shù)動態(tài)執(zhí)行的JS代碼。3. Function Code,即用戶自定義函數(shù)中的函數(shù)體JS代碼。基本原理在用戶自定義函數(shù)中,可以傳入?yún)?shù)、在函數(shù)中定義局部變量,函數(shù)體代碼可以使用這些入?yún)?、局部變?/p>
10、。背后的機制是什么樣呢?當JS執(zhí)行流進入函數(shù)時,JavaScript引擎在內(nèi)部創(chuàng)建一個對象,叫做Variable Object。對應(yīng)函數(shù)的每一個參數(shù),在Variable Object上添加一個屬性,屬性的名字、值與參數(shù)的名字、值相同。函數(shù)中每聲明一個變量,也會在Variable Object上添加一個屬性,名字就是變量名,因此為變量賦值就是給Variable Object對應(yīng)的屬性賦值。在函數(shù)中訪問參數(shù)或者局部變量時,就是在variable Object上搜索相應(yīng)的屬性,返回其值。一般情況下Variable Object是一個內(nèi)部對象,JS代碼中無法直接訪問。規(guī)范中對其實現(xiàn)方式也不做要求,因此
11、它可能只是引擎內(nèi)部的一種數(shù)據(jù)結(jié)構(gòu)。大致處理方式就這樣,但作用域的概念不只這么簡單,例如函數(shù)體中可以使用全局變量、函數(shù)嵌套定義時情況更復(fù)雜點。這些情況下怎樣處理? JavaScript引擎將不同執(zhí)行位置上的Variable Object按照規(guī)則構(gòu)建一個鏈表,在訪問一個變量時,先在鏈表的第一個Variable Object上查找,如果沒有找到則繼續(xù)在第二個Variable Object上查找,直到搜索結(jié)束。這就是Scope/Scope Chain的大致概念。下面是各個方面詳細的處理。Global ObjectJavaScript的運行環(huán)境都必須存在一個唯一的全局對象-Global Object,例
12、如HTML中的window對象。Global Object是一個宿主對象,除了作為JavaScript運行時的全局容器應(yīng)具備的職責外,ECMA規(guī)范對它沒有額外要求。它包Math、 String、Date、parseInt等JavaScript中內(nèi)置的全局對象、函數(shù)(都作為Global Object的屬性),還可以包含其它宿主環(huán)境需要的一些屬性。Variable Object上面簡述了Variable Object的基本概念。創(chuàng)建Variable Object,將參數(shù)、局部變量設(shè)置為Variable Object屬性的處理過程叫做Variable Instatiation-變量實例化,后面結(jié)合S
13、cope Chain再進行詳細說明。Global CodeVariable Object就是Global Object,這是Variable Object唯一特殊的地方(指它是內(nèi)部的無法訪問的對象而言)。varglobalVariable=WWW;document.write(window.globalVariable);/result:WWW上面代碼在Global Code方式下運行,根據(jù)對Variable Object的處理,定義變量globalVariable時就會在Global Object(即window)對象上添加這個屬性,所以輸出是WWW這個值。Function CodeVari
14、able Object也叫做Activation Object(因為有一些差異存在,所以規(guī)范中重新取一個名字以示區(qū)別,Global Code/Eval Code中叫Variable Object,F(xiàn)unction Code中就叫做Activation Object)。每次進入函數(shù)執(zhí)行都會創(chuàng)建一個新的Activation Object對象,然后創(chuàng)建一個arguments對象并設(shè)置為Activation Object的屬性,再進行Variable Instantiation處理。在退出函數(shù)時,Activation Object會被丟棄(并不是內(nèi)存釋放,只是可以被垃圾回收了)。附arguments對
15、象的屬性:length: 為實際傳入?yún)?shù)的個數(shù)。注意,參考函數(shù)對象創(chuàng)建過程,函數(shù)對象上的length為函數(shù)定義時要求的參數(shù)個數(shù);callee: 為執(zhí)行的函數(shù)對象本身。目的是使函數(shù)對象能夠引用自己,例如需要遞歸調(diào)用的地方。function fnName(.) . 這樣定義函數(shù),它的遞歸調(diào)用可以在函數(shù)體內(nèi)使用fnName完成。var fn=function(.) . 這樣定義匿名函數(shù),在函數(shù)體內(nèi)無法使用名字引用自己,通過arguments.callee就可以引用自己而實現(xiàn)遞歸調(diào)用。參數(shù)列表: 調(diào)用者實際傳入的參數(shù)列表。這個參數(shù)列表提供一個使用索引訪問實際參數(shù)的方法。Variable Instant
16、iation處理時會在Activation Object對象上添加屬性,前提是函數(shù)聲明時有指定參數(shù)列表。如果函數(shù)聲明中不給出參數(shù)列表,或者實際調(diào)用參數(shù)個數(shù)與聲明時的不一樣,可以通過 arguments訪問各個參數(shù)。arguments中的參數(shù)列表與Activation Object上的參數(shù)屬性引用的是相同的參數(shù)對象(如果修改,在兩處都會反映出來)。規(guī)范并不要求arguments是一個數(shù)組對象,下面是一個測試:/PassedinFF2.0,IE7,Opera9.25,Safari3.0.4varargumentsLike=0:aaa,1:222,2:WWW,length:3,callee:func
17、tion();document.write(argumentsLike2+);/result:WWWdocument.write(argumentsLike1+);/result:222/converttheargumentsLiketoanArrayobject,justaswecandothisfortheargumentspropertyvararray=.slice.apply(argumentsLike);document.write(arrayinstanceofArray);/result:truedocument.write();document.write(array.rev
18、erse().join(|);/result:WWW|222|aaaEval CodeVariable Object就是調(diào)用eval時當前執(zhí)行上下文中的Variable Object。在Global Code中調(diào)用eval函數(shù),它的Variable Object就是Global Object;在函數(shù)中調(diào)用eval,它的Variable Object就是函數(shù)的Activation Object。/PassedinFF2.0,IE7,Opera9.25,Safari3.0.4functionfn(arg)varinnerVar=variableinfunction;eval(varevalVar=
19、variableineval;document.write(arg+);document.write(innerVar+););document.write(evalVar);fn(argumentsforfunction);輸出結(jié)果是:arguments for functionvariable in functionvariable in eval說明: eval調(diào)用中可以訪問函數(shù)fn的參數(shù)、局部變量;在eval中定義的局部變量在函數(shù)fn中也可以訪問,因為它們的Varible Object是同一個對象。Scope/Scope Chain首先Scope Chain是一個類似鏈表/堆棧的結(jié)構(gòu),
20、里面每個元素基本都是Variable Object/Activation Object。其次存在執(zhí)行上下文的地方都有當前Scope Chain,可以理解為Scope Chain就是執(zhí)行上下文的具體表現(xiàn)形式。Global CodeScope Chain只包含一個對象,即Global Object。在開始JavaScript代碼的執(zhí)行之前,引擎會創(chuàng)建好這個Scope Chain結(jié)構(gòu)。Function Code函數(shù)對象在內(nèi)部都有一個Scope屬性,用來記錄該函數(shù)所處位置的Scope Chain。創(chuàng)建函數(shù)對象時,引擎會將當前執(zhí)行環(huán)境的Scope Chain傳給Function的Construct方法。
21、Construct會創(chuàng)建一個新的Scope Chain,內(nèi)容與傳入的Scope Chain完全一樣,并賦給被創(chuàng)建函數(shù)的內(nèi)部Scope屬性。在前面函數(shù)對象創(chuàng)建過程一節(jié)中,這個處理位于步驟4和5之間。進入函數(shù)調(diào)用時,也會創(chuàng)建一個新的Scope Chain,包括同一個函數(shù)的遞歸調(diào)用,退出函數(shù)時這個Scope Chain被丟棄。新建的Scope Chain第一個對象是Activation Object,接下來的內(nèi)容與內(nèi)部Scope上存儲的Scope Chain內(nèi)容完全一樣。Eval Code進入Eval Code執(zhí)行時會創(chuàng)建一個新的Scope Chain,內(nèi)容與當前執(zhí)行上下文的Scope Chain完
22、全一樣。實例說明Scope Chain的原理就上面這些,必須結(jié)合JS代碼的執(zhí)行、Variable Instantiation的細節(jié)處理,才能理解上面這些如何產(chǎn)生作用,下面用一個簡單的場景來綜合說明。假設(shè)下面是一段JavaScript的Global Code:varouterVar1=variableinglobalcode;functionfn1(arg1,arg2)varinnerVar1=variableinfunctioncode;functionfn2()returnouterVar1+-+innerVar1+-+-+(arg1+arg2);returnfn2();varouterVa
23、r2=fn1(10,20);執(zhí)行處理過程大致如下:1. 初始化Global Object即windo0,0)20); 執(zhí)行處理過程大致如下:1. 初始化Global Object即window對象,Variable Object為window對象本身。創(chuàng)建Scope Chain對象,假設(shè)為scope_1,其中只包含window對象。2. 掃描JS源代碼(讀入源代碼、可能有詞法語法分析過程),從結(jié)果中可以得到定義的變量名、函數(shù)對象。按照掃描順序: 2.1 發(fā)現(xiàn)變量outerVar1,在window對象上添加outerVar1屬性,值為undefined; 2.2 發(fā)現(xiàn)函數(shù)fn1的定義,使用這個定
24、義創(chuàng)建函數(shù)對象,傳給創(chuàng)建過程的Scope Chain為scope_1。將結(jié)果添加到window的屬性中,名字為fn1,值為返回的函數(shù)對象。注意fn1的內(nèi)部Scope就是 scope_1。另外注意,創(chuàng)建過程并不會對函數(shù)體中的JS代碼做特殊處理,可以理解為只是將函數(shù)體JS代碼的掃描結(jié)果保存在函數(shù)對象的內(nèi)部屬性上,在函 數(shù)執(zhí)行時再做進一步處理。這對理解Function Code,尤其是嵌套函數(shù)定義中的Variable Instantiation很關(guān)鍵; 2.3 發(fā)現(xiàn)變量outerVar2,在window對象上添加outerVar2屬性,值為undefined;3. 執(zhí)行outerVar1賦值語句,賦
25、值為variable in global code。4. 執(zhí)行函數(shù)fn1,得到返回值: 4.1 創(chuàng)建Activation Object,假設(shè)為activation_1;創(chuàng)建一個新的Scope Chain,假設(shè)為scope_2,scope_2中第一個對象為activation_1,第二個對象為window對象(取自fn1的 Scope,即scope_1中的內(nèi)容); 4.2 處理參數(shù)列表。在activation_1上設(shè)置屬性arg1、arg2,值分別為10、20。創(chuàng)建arguments對象并進行設(shè)置,將arguments設(shè)置為activation_1的屬性; 4.3 對fn1的函數(shù)體執(zhí)行類似步驟2
26、的處理過程: 4.3.1 發(fā)現(xiàn)變量innerVar1,在activation_1對象上添加innerVar1屬性,值為undefine; 4.3.2 發(fā)現(xiàn)函數(shù)fn2的定義,使用這個定義創(chuàng)建函數(shù)對象,傳給創(chuàng)建過程的Scope Chain為scope_2(函數(shù)fn1的Scope Chain為當前執(zhí)行上下文的內(nèi)容)。將結(jié)果添加到activation_1的屬性中,名字為fn2,值為返回的函數(shù)對象。注意fn2的內(nèi)部 Scope就是scope_2; 4.4 執(zhí)行innerVar1賦值語句,賦值為variable in function code。 4.5 執(zhí)行fn2: 4.5.1 創(chuàng)建Activation
27、 Object,假設(shè)為activation_2;創(chuàng)建一個新的Scope Chain,假設(shè)為scope_3,scope_3中第一個對象為activation_2,接下來的對象依次為activation_1、window 對象(取自fn2的Scope,即scope_2); 4.5.2 處理參數(shù)列表。因為fn2沒有參數(shù),所以只用創(chuàng)建arguments對象并設(shè)置為activation_2的屬性。 4.5.3 對fn2的函數(shù)體執(zhí)行類似步驟2的處理過程,沒有發(fā)現(xiàn)變量定義和函數(shù)聲明。 4.5.4 執(zhí)行函數(shù)體。對任何一個變量引用,從scope_3上進行搜索,這個示例中,outerVar1將在window上找到
28、;innerVar1、arg1、arg2將在activation_1上找到。 4.5.5 丟棄scope_3、activation_2(指它們可以被垃圾回收了)。 4.5.6 返回fn2的返回值。 4.6 丟棄activation_1、scope_2。 4.7 返回結(jié)果。5. 將結(jié)果賦值給outerVar2。其它情況下Scope Chain、Variable Instantiation處理類似上面的過程進行分析就行了。根據(jù)上面的實例說明,就可以解釋下面這個測試代碼的結(jié)果:/PassedinFF2.0,IE7,Opera9.25,Safari3.0.4functionfn(obj)return/
29、testwhether exists a local variableouterVar on objexists:Ototype.hasOwnProperty.call(obj,outerVar),/testthevalueofthevariableouterVarvalue:obj.outerVar;varresult1=fn(window);varouterVar=WWW; varresult2=fn(window);document.write(result1.exists+result1.value);/result:trueundefineddocument.wri
30、te();document.write(result2.exists+result2.value);/result:trueWWWresult1調(diào)用的地方,outerVar聲明和賦值的語句還沒有被執(zhí)行,但是測試結(jié)果window對象已經(jīng)擁有一個本地屬性outerVar,其值為 undefined。result2的地方outerVar已經(jīng)賦值,所以window.outerVar的值已經(jīng)有了。實際使用中不要出現(xiàn)這種先使用, 后定義的情況,否則某些情況下會有問題,因為會涉及到一些規(guī)范中沒有提及,不同廠商實現(xiàn)方式上不一致的地方。一些特殊處理1. with(obj) . 這個語法的實現(xiàn)方式,是在當前的Sc
31、ope Chain最前面位置插入obj這個對象,這樣就會先在obj上搜索是否有相應(yīng)名字的屬性存在。其它類似的還有catch語句。2. 前面對arguments對象的詳細說明中,提到了對函數(shù)遞歸調(diào)用的支持問題,了解到了匿名函數(shù)使用arguments.callee來實現(xiàn)引用自己,而 命名函數(shù)可以在函數(shù)體內(nèi)引用自己,根據(jù)上面Scope Chain的工作原理我們還無法解釋這個現(xiàn)象,因為這里有個特殊處理。任何時候創(chuàng)建一個命名函數(shù)對象時,JavaScript引擎會在當前執(zhí)行上下文Scope Chain的最前面插入一個對象,這個對象使用new Object()方式創(chuàng)建,并將這個Scope Chain傳給Fu
32、nction的構(gòu)造函數(shù)Construct,最終創(chuàng)建出來的函數(shù)對象內(nèi)部Scope上將包含這個object對象。創(chuàng) 建過程返回之后,JavaScript引擎在object上添加一個屬性,名字為函數(shù)名,值為返回的函數(shù)對象,然后從當前執(zhí)行上下文的Scope Chain中移除它。這樣函數(shù)對象的Scope Chain中第一個對象就是對自己的引用,而移除操作則確保了對函數(shù)對象創(chuàng)建處Scope Chain的恢復(fù)。this關(guān)鍵字處理執(zhí)行上下文包含的另一個概念是this關(guān)鍵字。Global Code中this關(guān)鍵字為Global Object;函數(shù)調(diào)用時this關(guān)鍵字為調(diào)用者,例如obj1.fn1(),在fn1中
33、this對象為obj1;Eval Code中this關(guān)鍵字為當前執(zhí)行上下文的Variable Object。在函數(shù)調(diào)用時,JavaScript提供一個讓用戶自己指定this關(guān)鍵字值的機會,即每個函數(shù)都有的call、apply方法。例如:fn1.call(obj1, arg1, arg2, .)或者fn1.apply(obj1, argArray),都是將obj1作為this關(guān)鍵字,調(diào)用執(zhí)行fn1函數(shù),后面的參數(shù)都作為函數(shù)fn1的參數(shù)。如果obj1為null或 undefined,則Global Object將作為this關(guān)鍵字的值;如果obj1不是Object類型,則轉(zhuǎn)化為Object類型。它
34、們之間的唯一區(qū)別在于,apply允許以數(shù)組的 方式提供各個參數(shù),而call方法必須一個一個參數(shù)的給。前面的測試示例代碼中有多處運用到了這個方法。例如window對象并沒有hasOwnProperty方法,使用Ototype.hasOwnProperty.call(window, propertyName)也可以測試它是否擁有某個本地屬性。JavaScript中的閉包Closures示例:/PassedinFF2.0,IE7,Opera9.25,Safari3.0.4functionouter()vara=aaa;varb=bbb;returnfunction()returna
35、+b;varinner=outer();document.write(inner();outer返回的是一個內(nèi)嵌函數(shù),內(nèi)嵌函數(shù)使用了outer的局部變量a和b。照理outer的局部變量在返回時就超出了作用域因此inner()調(diào)用無 法使用才對。這就是閉包Closure,即函數(shù)調(diào)用返回了一個內(nèi)嵌函數(shù),而內(nèi)嵌函數(shù)引用了外部函數(shù)的局部變量、參數(shù)等這些應(yīng)當被關(guān)閉(Close)了的資源。根據(jù)前面Scope Chain的理解可以解釋,返回的內(nèi)嵌函數(shù)已經(jīng)持有了構(gòu)造它時的Scope Chain,雖然outer返回導(dǎo)致這些對象超出了作用域、生存期范圍,但JavaScript使用自動垃圾回收來釋放對象內(nèi)存: 按照
36、規(guī)則定期檢查,對象沒有任何引用才被釋放。因此上面的代碼能夠正確運行。w對象,Variable Object為window對象本身。創(chuàng)建Scope Chain對象,假設(shè)為scope_1,其中只包含window對象。2. 掃描JS源代碼(讀入源代碼、可能有詞法語法分析過程),從結(jié)果中可以得到定義的變量名、函數(shù)對象。按照掃描順序: 2.1 發(fā)現(xiàn)變量outerVar1,在window對象上添加outerVar1屬性,值為undefined; 2.2 發(fā)現(xiàn)函數(shù)fn1的定義,使用這個定義創(chuàng)建函數(shù)對象,傳給創(chuàng)建過程的Scope Chain為scope_1。將結(jié)果添加到window的屬性中,名字為fn1,值為
37、返回的函數(shù)對象。注意fn1的內(nèi)部Scope就是 scope_1。另外注意,創(chuàng)建過程并不會對函數(shù)體中的JS代碼做特殊處理,可以理解為只是將函數(shù)體JS代碼的掃描結(jié)果保存在函數(shù)對象的內(nèi)部屬性上,在函 數(shù)執(zhí)行時再做進一步處理。這對理解Function Code,尤其是嵌套函數(shù)定義中的Variable Instantiation很關(guān)鍵; 2.3 發(fā)現(xiàn)變量outerVar2,在window對象上添加outerVar2屬性,值為undefined;3. 執(zhí)行outerVar1賦值語句,賦值為variable in global code。4. 執(zhí)行函數(shù)fn1,得到返回值: 4.1 創(chuàng)建Activation
38、Object,假設(shè)為activation_1;創(chuàng)建一個新的Scope Chain,假設(shè)為scope_2,scope_2中第一個對象為activation_1,第二個對象為window對象(取自fn1的 Scope,即scope_1中的內(nèi)容); 4.2 處理參數(shù)列表。在activation_1上設(shè)置屬性arg1、arg2,值分別為10、20。創(chuàng)建arguments對象并進行設(shè)置,將arguments設(shè)置為activation_1的屬性; 4.3 對fn1的函數(shù)體執(zhí)行類似步驟2的處理過程: 4.3.1 發(fā)現(xiàn)變量innerVar1,在activation_1對象上添加innerVar1屬性,值為un
39、define; 4.3.2 發(fā)現(xiàn)函數(shù)fn2的定義,使用這個定義創(chuàng)建函數(shù)對象,傳給創(chuàng)建過程的Scope Chain為scope_2(函數(shù)fn1的Scope Chain為當前執(zhí)行上下文的內(nèi)容)。將結(jié)果添加到activation_1的屬性中,名字為fn2,值為返回的函數(shù)對象。注意fn2的內(nèi)部 Scope就是scope_2; 4.4 執(zhí)行innerVar1賦值語句,賦值為variable in function code。 4.5 執(zhí)行fn2: 4.5.1 創(chuàng)建Activation Object,假設(shè)為activation_2;創(chuàng)建一個新的Scope Chain,假設(shè)為scope_3,scope_3中
40、第一個對象為activation_2,接下來的對象依次為activation_1、window 對象(取自fn2的Scope,即scope_2); 4.5.2 處理參數(shù)列表。因為fn2沒有參數(shù),所以只用創(chuàng)建arguments對象并設(shè)置為activation_2的屬性。 4.5.3 對fn2的函數(shù)體執(zhí)行類似步驟2的處理過程,沒有發(fā)現(xiàn)變量定義和函數(shù)聲明。 4.5.4 執(zhí)行函數(shù)體。對任何一個變量引用,從scope_3上進行搜索,這個示例中,outerVar1將在window上找到;innerVar1、arg1、arg2將在activation_1上找到。 4.5.5 丟棄scope_3、activa
41、tion_2(指它們可以被垃圾回收了)。 4.5.6 返回fn2的返回值。 4.6 丟棄activation_1、scope_2。 4.7 返回結(jié)果。5. 將結(jié)果賦值給outerVar2。其它情況下Scope Chain、Variable Instantiation處理類似上面的過程進行分析就行了。根據(jù)上面的實例說明,就可以解釋下面這個測試代碼的結(jié)果:/PassedinFF2.0,IE7,Opera9.25,Safari3.0.4functionfn(obj)return/testwhether exists a local variableouterVar on objexists:Obje
42、totype.hasOwnProperty.call(obj,outerVar),/testthevalueofthevariableouterVarvalue:obj.outerVar;varresult1=fn(window);varouterVar=WWW; varresult2=fn(window);document.write(result1.exists+result1.value);/result:trueundefineddocument.write();document.write(result2.exists+result2.value);/result:tru
43、eWWWresult1調(diào)用的地方,outerVar聲明和賦值的語句還沒有被執(zhí)行,但是測試結(jié)果window對象已經(jīng)擁有一個本地屬性outerVar,其值為 undefined。result2的地方outerVar已經(jīng)賦值,所以window.outerVar的值已經(jīng)有了。實際使用中不要出現(xiàn)這種先使用, 后定義的情況,否則某些情況下會有問題,因為會涉及到一些規(guī)范中沒有提及,不同廠商實現(xiàn)方式上不一致的地方。一些特殊處理1. with(obj) . 這個語法的實現(xiàn)方式,是在當前的Scope Chain最前面位置插入obj這個對象,這樣就會先在obj上搜索是否有相應(yīng)名字的屬性存在。其它類似的還有catch語句。2. 前面對arguments對象的詳細說明中,提到了對函數(shù)遞歸調(diào)用
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 江蘇安全技術(shù)職業(yè)學院《腫瘤放射治療學》2023-2024學年第一學期期末試卷
- 老年人臥床的護理措施
- 新疆農(nóng)業(yè)大學《多元音樂文化與世界名曲欣賞》2023-2024學年第一學期期末試卷
- 河北省張家口市涿鹿縣2024-2025學年初三第一次模擬考試(化學試題文)試卷含解析
- 2025年山東省萊蕪市萊城區(qū)茶業(yè)口鎮(zhèn)腰關(guān)中學初三下學期十月月考化學試題含解析
- 廣東職業(yè)技術(shù)學院《生物納米與高分子材料》2023-2024學年第二學期期末試卷
- 浙江廣廈建設(shè)職業(yè)技術(shù)大學《馬克思基本原理》2023-2024學年第二學期期末試卷
- 湖南網(wǎng)絡(luò)工程職業(yè)學院《地下工程結(jié)構(gòu)》2023-2024學年第一學期期末試卷
- 北京科技經(jīng)營管理學院《土力學理論與實踐》2023-2024學年第二學期期末試卷
- 廣東工業(yè)大學《電路板設(shè)計CAD》2023-2024學年第二學期期末試卷
- 入團申請書紙
- 2025年廣東廣州市高三高考地理模擬試卷試題(含答案詳解)
- 收費站防雷電安全知識
- 2006年上海市中考滿分作文《我們的名字叫坐在“最后一排”的人》
- 2025年中國藥學會公開招聘工作人員3人歷年高頻重點提升(共500題)附帶答案詳解
- 機器學習(完整版課件)
- AEO貿(mào)易安全培訓
- 《簡歷制作培訓》課件
- 食品安全案例-課件-案例十二-蘇丹紅事件
- 肝硬化失代償期
- 2023年非車險核??荚囌骖}模擬匯編(共396題)
評論
0/150
提交評論