久久久久久久视色,久久电影免费精品,中文亚洲欧美乱码在线观看,在线免费播放AV片

<center id="vfaef"><input id="vfaef"><table id="vfaef"></table></input></center>

    <p id="vfaef"><kbd id="vfaef"></kbd></p>

    
    
    <pre id="vfaef"><u id="vfaef"></u></pre>

      <thead id="vfaef"><input id="vfaef"></input></thead>

    1. 站長資訊網
      最全最豐富的資訊網站

      深入理解JS數據類型、預編譯、執(zhí)行上下文等JS底層機制

      JavaScript由文檔對象模型DOM、瀏覽器對象模型BOM以及它的核心ECMAScript這三部分組成,本篇文章帶來了JavaScript中的底層原理知識,希望對大家有幫助。

      深入理解JS數據類型、預編譯、執(zhí)行上下文等JS底層機制

      JavaScript是一門直譯式的解釋型腳本語言,它具有動態(tài)性、弱類型、基于原型等特點。JavaScript植根于我們使用的Web瀏覽器中,它的解釋器為瀏覽器中的JavaScript引擎。這一門廣泛用于客戶端的腳本語言,最早是為了處理以前由服務器端語言負責的一些輸入驗證操作,隨著Web時代的發(fā)展,JavaScript不斷發(fā)展壯大,成為一門功能全面的編程語言。它的用途早已不再局限于當初簡單的數據驗證,而是具備了與瀏覽器窗口及其內容等幾乎所有方面交互的能力。它既是一門非常簡單的語言,又是一門及其復雜的語言,要想真正精通JavaScript,我們就必須深入的去了解它的一些底層設計原理。本文將參考《JavaScript高級程序設計》和《你不知道的JS》系列叢書,為大家講解一些關于JavaScript的底層知識。

      數據類型

      按照存儲方式,JavaScript的數據類型可以分為兩種,原始數據類型(原始值)和引用數據類型(引用值)。

      原始數據類型目前有六種,包括Number、String、Boolean、Null、Undefined、Symbol(ES6),這些類型是可以直接操作的保存在變量中的實際值。原始數據類型存放在棧中,數據大小確定,它們是直接按值存放的,所以可以直接按值訪問。

      引用數據類型則為Object,在JavaScript中除了原始數據類型以外的都是Object類型,包括數組、函數、正則表達式等都是對象。引用類型是存放在堆內存中的對象,變量是保存在棧內存中的一個指向堆內存中對象的引用地址。當定義了一個變量并初始化為引用值,若將它賦給另一個變量,則這兩個變量保存的是同一個地址,指向堆內存中的同一個內存空間。如果通過其中一個變量去修改引用數據類型的值,另一個變量也會跟著改變。

      對于原始數據類型,除了null比較特殊(null會被認為是一個空的對象引用),其它的我們可以用typeof進行準確判斷:

      表達式

      返回值

      typeof 123

      'number'

      typeof "abc"

      'string'

      typeof true

      'boolean'

      typeof null

      'object'

      typeof undefined

      'undefined'

      typeof unknownVariable(未定義的變量)

      'undefined'

      typeof Symbol()

      ‘symbol’

      typeof function() {}

      'function'

      typeof {}

      'object'

      typeof []

      'object'

      typeof(/[0-9,a-z]/)

      ‘object’

      對于null類型,可以使用全等操作符進行判斷。一個已經聲明但未初始化的變量值會默認賦予undefined (也可以手動賦予undefined),在JavaScript中,使用相等操作符==無法區(qū)分null和undefined,ECMA-262規(guī)定對它們的相等性測試要返回true。要準確區(qū)分兩個值,需要使用全等操作符===。

      深入理解JS數據類型、預編譯、執(zhí)行上下文等JS底層機制

      對于引用數據類型,除了function在方法設計上比較特殊,可以用typeof進行準確判斷,其它的都返回object類型。我們可以用instanceof 對引用類型值進行判斷。instanceof 會檢測一個對象A是不是另一個對象B的實例,它在底層會查看對象B是否在對象A的原型鏈上存在著(實例和原型鏈文章后面會講)。如果存在,則返回true,如果不在則返回false。

      表達式

      返回值

      [1,2,3] instanceof Array

      ‘true’

      function foo(){ } instanceof Function

      ‘true’

      /[0-9,a-z]/ instanceof RegExp

      ‘true’

      new Date() instanceof Date

      ‘true’

      {name:”Alan”,age:”22”} instanceof Object

      ‘true’

      由于所有引用類型值都是Object的實例,所以用instance操作符對它們進行Object的判斷,結果也會返回true。

      表達式

      返回值

      [1,2,3] instanceof Object

      ‘true’

      function foo(){ } instanceof Object

      ‘true’

      /[0-9,a-z]/ instanceof Object

      ‘true’

      new Date() instanceof Object

      ‘true’

      當然,還有一種更為強大的方法,可以精準的判斷任何JavaScript中的任何數據類型,那就是Object.prototype.toString.call() 方法。在ES5中,所有對象(原生對象和宿主對象)都有一個內部屬性[[Class]],它的值是一個字符串,記錄了該對象的類型。目前包括"Array", "Boolean", "Date", "Error", "Function", "Math", "Number", "Object", "RegExp", "String",“Arguments”, "JSON","Symbol”。通過Object.prototype.toString() 方法可以用來查看該內部屬性,除此自外沒有其它方法。

      在Object.prototype.toString()方法被調用時,會執(zhí)行以下步驟:1.獲取this對象的[[Class]]屬性值(關于this對象文章后面會講)。2.將該值放在兩個字符串”[object ” 與 “]” 中間并拼接起來。3.返回拼接完的字符串。

      當遇到this的值為null時,Object.prototype.toString()方法直接返回”[object Null]”。當遇到this的值為undefined時,直接返回”[object Undefined]”。

      表達式

      返回值

      Object.prototype.toString.call(123)

      [object Number]

      Object.prototype.toString.call(“abc”)

      [object String]

      Object.prototype.toString.call(true)

      [object Boolean]

      Object.prototype.toString.call(null)

      [object Null]

      Object.prototype.toString.call(undefined)

      [object Undefined]

      Object.prototype.toString.call(Symbol())

      [object Symbol]

      Object.prototype.toString.call(function foo(){})

      [object Function]

      Object.prototype.toString.call([1,2,3])

      [object Array]

      Object.prototype.toString.call({name:”Alan” })

      [object Object]

      Object.prototype.toString.call(new Date())

      [object Date]

      Object.prototype.toString.call(RegExp())

      [object RegExp]

      Object.prototype.toString.call(window.JSON)

      [object JSON]

      Object.prototype.toString.call(Math)

      [object Math]

      call()方法可以改變調用Object.prototype.toString()方法時this的指向,使它指向我們傳入的對象,因此能獲取到我們傳入對象的[[Class]]屬性(使用Object.prototype.toString.apply()也能達到同樣的效果)。

      JavaScript的數據類型也是可以轉換的,數據類型轉換分為兩種方式:顯示類型轉換和隱式類型轉換。

      顯示類型轉換可以調用方法有Boolean()、String()、Number()、parseInt()、parseFloat()和toString() (null和undefined值沒有這個方法),它們各自的用途一目了然,這里就不一一介紹了。

      由于JavaScript是弱類型語言,在使用算術運算符時,運算符兩邊的數據類型可以是任意的,不用像Java或C語言那樣指定相同的類型,引擎會自動為它們進行隱式類型轉換。隱式類型轉換不像顯示類型轉換那么直觀,主要是三種轉換方式:
      1. 將值轉換為原始值:toPrimitive()

      2. 將值轉換為數字:toNumber()

      3. 將值轉換為字符串:toString()

      一般來說,當對數字和字符串進行相加操作時,數字會被轉換成字符串;當進行真值判斷時(如if、||、&&),參數會被轉換成布爾值;當進行比較運算、算術運算或自增減運算時,參數會被轉換成Number值;當對象需要進行隱式類型轉換時,會取得對象的toString()方法或valueOf()方法的返回值。

      深入理解JS數據類型、預編譯、執(zhí)行上下文等JS底層機制

      關于NaN:

      NaN是一個特殊的數值,表示非數值。首先,任何涉及NaN的運算操作都會返回NaN。其次,NaN與任何值都不相等,包括NaN本身。ECMAScript定義了一個isNaN()函數,可以用來測試某個參數是否為“非數值”。它首先會嘗試將參數隱式轉換為數值,如果無法轉換為數值則返回true。

      深入理解JS數據類型、預編譯、執(zhí)行上下文等JS底層機制

      我們可以先通過typeof判斷是否為Number類型,再通過isNaN來判斷當前數據是否為NaN。

      關于字符串:

      JavaScript中的字符串是不可變的,字符串一旦被創(chuàng)建,它們的值就不能改變。要改變某個變量保存的字符串,首先要銷毀原來的字符串,然后再用另一個包含新值的字符串填充該變量。這個過程在后臺發(fā)生,而這也是某些老版本瀏覽器在拼接字符串時速度很慢的原因所在。

      其實為了便于操作基本類型值,ECMAScript還提供了3個特殊的引用類型:Boolean、Number和String。原始數據類型是沒有屬性和方法的,當我們在原始類型值上調用方法讀取它們時,訪問過程會處于一種讀取模式,后臺會創(chuàng)建一個相應的原始包裝類型的對象,從而讓我們能夠調用一些方法來操作這些數據。這個過程分為三個步驟:1.創(chuàng)建原始包裝類型的實例 2.在實例上調用指定的方法 3.銷毀這個實例。
      引用類型與原始包裝類型的主要區(qū)別是對象的生存周期,自動創(chuàng)建的原始包裝類型對象,只存在于一行代碼的執(zhí)行瞬間,然后立即被銷毀,因此我們不能在運行時為原始類型值添加屬性和方法。

      預編譯

      在《你不知道的JavaScript》一書中作者表示過,盡管將JavaScript歸類為“動態(tài)語言”或“解釋執(zhí)行語言”,但事實上它是一門編譯語言。JavaScript運行分為三個步驟:1.語法分析 2.預編譯 3.解釋執(zhí)行。語法分析和解釋執(zhí)行都不難理解,一個是檢查代碼是否有語法錯誤,一個則負責將程序一行一行的執(zhí)行,但JavaScript中的預編譯階段卻稍微比較復雜。

      任何JavaScript代碼在執(zhí)行前都要進行編譯,編譯過程大部分情況下發(fā)生在代碼執(zhí)行前的幾微秒內。編譯階段JavaScript引擎會從當前代碼執(zhí)行作用域開始,對代碼進行RHS查詢,以獲取變量的值。接著在執(zhí)行階段引擎會執(zhí)行LHS查詢,對變量進行賦值。

      在編譯階段,JavaScript引擎的一部分工作就是找到所有的聲明,并用合適的作用域將它們關聯起來。在預編譯過程,如果是在全局作用域下,JavaScript引擎首先會在全局作用域上創(chuàng)建一個全局對象(GO對象,Global Object),并將變量聲明和函數聲明進行提升。提升后的變量先默認初始化為undefined,而函數則將整個函數體進行提升(如果是以函數表達式的形式定義函數,則應用變量提升的規(guī)則),然后將它們存放到全局變量中。函數聲明的提升會優(yōu)先于變量聲明的提升,對于變量聲明來說,重復出現的var聲明會被引擎忽略,而后面出現的函數聲明可以覆蓋前面的函數聲明(ES6新的變量聲明語法let情況稍稍有點不一樣,這里暫時先不討論)

      函數體內部是一塊獨立的作用域,在函數體內部也會進行預編譯階段。在函數體內部,首先會創(chuàng)建一個活動對象(AO對象,Active Object),并將形參和變量聲明以及函數體內部的函數聲明進行提升,形參和變量初始化為undefined,內部函數依然為內部函數體本身,然后將它們存放到活動對象中。

      編譯階段結束后,就會執(zhí)行JavaScript代碼。執(zhí)行過程根據先后順序依次對變量或形參進行賦值操作。引擎會在作用域上查找是否有對應的變量聲明或形參聲明,如果找到了就會對它們進行賦值操作。對于非嚴格模式來說,若變量未經聲明就進行賦值,引擎會在全局環(huán)境自動隱式地為該變量創(chuàng)建一個聲明,但對于嚴格模式來說對未經聲明的變量進行賦值操作則會報錯。因為JavaScript執(zhí)行是單線程的,所以如果在賦值操作(LHS查詢)執(zhí)行前就先對變量進行獲取(RHS查詢)并輸出,會得到undefined的結果,因為此時變量還未賦值。

      執(zhí)行環(huán)境與作用域

      每個函數都是Function對象的一個實例,在JavaScript中,每個對象都有一個僅供JavaScript引擎存取的內部屬性—— [[Scope]]。對于函數來說,[[Scope]]屬性包含了函數被創(chuàng)建的作用域中對象的集合——作用域鏈。當在全局環(huán)境中創(chuàng)建一個函數時,該函數的作用域鏈便會插入一個全局對象,包含所有在全局范圍內定義的變量。

      深入理解JS數據類型、預編譯、執(zhí)行上下文等JS底層機制

      深入理解JS數據類型、預編譯、執(zhí)行上下文等JS底層機制

      內部作用域可以訪問外部作用域,但外部作用域無法訪問內部作用域。由于JavaScript沒有塊級作用域,因此在if語句或者for循環(huán)語句中定義的變量是可以在語句外部訪問到的。在ES6之前,javascript只有全局作用域和函數作用域,ES6新增了塊級作用域的機制。

      而當該函數被執(zhí)行時,會為執(zhí)行函數創(chuàng)建一個稱為執(zhí)行環(huán)境(execution context,也稱為執(zhí)行上下文)的內部對象。每個執(zhí)行環(huán)境都有自己的作用域鏈,當執(zhí)行環(huán)境被創(chuàng)建時,它的作用域鏈頂端先初始化為當前運行函數的[[Scope]]屬性中的對象。緊接著,函數運行時的活動對象(包括所有局部變量、命名參數、arguments參數集合和this)也會被創(chuàng)建并推入作用域鏈的最頂端。

      深入理解JS數據類型、預編譯、執(zhí)行上下文等JS底層機制

      深入理解JS數據類型、預編譯、執(zhí)行上下文等JS底層機制

      函數每次執(zhí)行時對應的執(zhí)行環(huán)境都是獨一無二的,多次調用同一個函數就會導致創(chuàng)建多個執(zhí)行環(huán)境。當函數執(zhí)行完畢,執(zhí)行環(huán)境就會被銷毀。當執(zhí)行環(huán)境被銷毀,活動對象也隨之銷毀(全局執(zhí)行環(huán)境會等到應用程序退出時才會被銷毀,如關閉網頁或瀏覽器)

      函數執(zhí)行過程中,每遇到一個變量,都會經歷一次標識符解析過程,以決定從哪里獲取或存儲數據。標識符解析是沿著作用域鏈一級一級地搜索標識符的過程,全局變量始終都是作用域鏈的最后一個對象(即window對象)。

      在JavaScript中,有兩個語句可以在執(zhí)行時臨時改變作用域鏈。第一個是with語句。with語句會創(chuàng)建一個可變對象,包含參數指定對象的所有屬性,并將該對象推入作用域鏈的首位,這意味著函數的活動對象被擠到作用域鏈的第二位。這樣雖然使得訪問可變對象的屬性非???,但訪問局部變量等的速度就變慢了。第二條能改變執(zhí)行環(huán)境作用域鏈的語句是try-catch語句中的catch子句。當try代碼塊中發(fā)生錯誤,執(zhí)行過程會自動跳轉到catch子句,然后把異常對象推入一個變量對象并置于作用域的首位。在catch代碼塊內部,函數所有局部變量將會放在第二個作用域鏈對象中。一旦catch子句執(zhí)行完畢,作用域鏈就會返回到之前的狀態(tài)。

      構造函數

      JavaScript中的構造函數可以用來創(chuàng)建特定類型的對象。為了區(qū)別于其它函數,構造函數一般使用大寫字母開頭。不過在JavaScript中這并不是必須的,因為JavaScript不存在定義構造函數的特殊語法。在JavaScript中,構造函數與其它函數的唯一區(qū)別,就在于調用它們的方式不同。任何函數,只要通過new操作符來調用,就可以作為構造函數。

      JavaScript函數有四種調用模式:1.獨立函數調用模式,如foo(arg)。2.方法調用模式,如obj.foo(arg)。3.構造器調用模式,如new foo(arg)。4.call/apply調用模式,如foo.call(this,arg1,arg2)或foo.apply(this,args) (此處的args是一個數組)。

      要創(chuàng)建構造函數的實例,發(fā)揮構造函數的作用,就必須使用new操作符。當我們使用new操作符實例化構造函數時,構造函數內部會執(zhí)行以下步驟:
      1.隱式創(chuàng)建一個this空對象
      2.執(zhí)行構造函數中的代碼(為當前this對象添加屬性)
      3.隱式返回當前this對象

      深入理解JS數據類型、預編譯、執(zhí)行上下文等JS底層機制

      如果構造函數顯示的返回一個對象,那么實例為這個返回的對象,否則則為隱式返回的this對象。

      當我們調用構造函數創(chuàng)建實例后,實例便具備構造函數所有的實例屬性和方法。對于通過構造函數創(chuàng)建的不同實例,它們之間的實例屬性和方法都是各自獨立的。那怕是同名的引用類型值,不同實例之間也不會相互影響。

      原型與原型鏈

      原型和原型鏈既是JavaScript這門語言的精髓之一,也是這門語言的難點之一。原型prototype(顯式原型)是函數特有的屬性,任何時候,只要創(chuàng)建了一個函數,這個函數就會自動創(chuàng)建一個prototype屬性,并指向該函數的原型對象。所有原型對象都會自動獲得一個constructor(構造者,也可翻譯為構造函數)屬性,這個屬性包含一個指向prototype屬性所在函數(即構造函數本身)的指針。而當我們通過構造函數創(chuàng)建一個實例后,該實例內部將包含一個[[Prototype]]的內部屬性(隱式原型),同樣也指向構造函數的原型對象。在Firefox、Safari和Chrome瀏覽器中,每個對象都可以通過__proto__屬性訪問它們的[[Prototype]]屬性。而對其它瀏覽器而言,這個屬性對腳本則是完全不可見的。

      深入理解JS數據類型、預編譯、執(zhí)行上下文等JS底層機制

      深入理解JS數據類型、預編譯、執(zhí)行上下文等JS底層機制

      構造函數的prototype屬性和實例的[[Prototype]]都是指向構造函數的原型對象,實例的 [[Prototype]] 屬性與構造函數之間并沒有直接的關系。要想知道實例的 [[Prototype]] 屬性是否指向某個構造函數的原型對象,我們可以使用isPrototypeOf()或者Object.getPrototypeOf() 方法。

      深入理解JS數據類型、預編譯、執(zhí)行上下文等JS底層機制

      每當讀取某個對象實例的某個屬性時,都會執(zhí)行一次搜索,目標是具有給定名字的屬性。搜索首先從對象實例本身開始,如果在實例中找到了具有給定名稱的屬性,就返回該屬性的值;如果沒有找到,則繼續(xù)搜索該對象[[Prototype]]屬性指向的原型對象,在原型對象中查找給定名稱的屬性,如果找到再返回該屬性的值。

      深入理解JS數據類型、預編譯、執(zhí)行上下文等JS底層機制

      深入理解JS數據類型、預編譯、執(zhí)行上下文等JS底層機制

      判斷對象是哪個構造函數的直接實例,可以直接在實例上訪問constructor屬性,實例會通過[[Prototype]]讀取原型對象上的constructor屬性返回構造函數本身。

      原型對象中的值可以通過對象實例訪問,但卻不能通過對象實例修改。如果在實例中添加一個與實例原型對象同名的屬性,那我們就在實例中創(chuàng)建該屬性,這個實例屬性會阻止我們訪問原型對象中的那個屬性,但不會修改那個屬性。簡單將該實例屬性設為null并不能恢復訪問原型對象中該屬性的連接,若要恢復訪問原型對象中的該屬性,可以用delete操作符完全刪除對象實例的該屬性。

      深入理解JS數據類型、預編譯、執(zhí)行上下文等JS底層機制

      使用hasOwnProperty()方法可以檢測一個屬性是存在于實例中,還是存在于原型中。這個方法只有在給定屬性存在于對象實例中時,才會返回true。若要取得對象自身所有可枚舉的實例屬性,可以使用ES5的Object.keys() 方法。若要獲取所有實例屬性,無論是否可枚舉,可以使用Object.getOwnPropertyNames() 方法。

      深入理解JS數據類型、預編譯、執(zhí)行上下文等JS底層機制

      原型具有動態(tài)性,對原型對象所做的任何修改都能立即從實例上反應出來,但如果是重寫整個原型對象,情況就不一樣了。調用構造函數會為對象實例添加一個指向最初原型對象的 [[Prototype]] 指針,而重寫整個原型對象后,構造函數指向新的原型對象,所有的原型對象屬性和方法都存在與新的原型對象上;而對象實例還指向最初的原型對象,這樣一來構造函數與最初原型對象之間指向同一個原型對象產生的聯系就被切斷了,因為它們分別指向了不同的原型對象。

      深入理解JS數據類型、預編譯、執(zhí)行上下文等JS底層機制

      深入理解JS數據類型、預編譯、執(zhí)行上下文等JS底層機制

      若要恢復這種聯系,可以在構造函數prototype重寫后再實例化對象實例,或者修改對象實例的__proto__屬性重新指向構造函數新的原型對象。

      深入理解JS數據類型、預編譯、執(zhí)行上下文等JS底層機制

      JavaScript將原型鏈作為實現繼承的主要方式,它利用原型讓一個引用類型繼承另一個引用類型的屬性和方法。構造函數的實例有一個指向原型對象的 [[Prototype]] 屬性,當我們讓構造函數的原型對象等于另一個類型的實例,原型對象也將包含一個指向另一個原型的 [[Prototype]] 指針,假如另一個原型又是另一個類型的實例…如此層層遞進,就構成了實例與原型的鏈條。這就是所謂原型鏈的基本概念。

      深入理解JS數據類型、預編譯、執(zhí)行上下文等JS底層機制

      深入理解JS數據類型、預編譯、執(zhí)行上下文等JS底層機制

      原型鏈擴展了原型搜索機制,當讀取一個實例屬性時,首先會在實例中搜索該屬性。如果沒有找到該屬性,則會繼續(xù)搜索實例[[Prototype]] 指向的原型對象,原型對象此時也變成了另一個構造函數的實例,如果該原型對象上也找不到,就會繼續(xù)搜索該原型對象[[Prototype]] 指向的另一個原型對象…搜索過程沿著原型鏈不斷向上搜索,在找不到指定屬性或者方法的情況下,搜索過程就會一環(huán)一環(huán)地執(zhí)行到原型鏈末端才會停下來。

      如果不對函數的原型對象進行修改,所有引用類型都有一個[[Prototype]] 屬性默認指向Object的原型對象。因此,所有函數的默認原型都是Object的實例,這也正是所有自定義類型都會繼承toString()、valueOf() 等默認方法的根本原因。可以使用instanceof操作符或isPrototypeOf() 方法來判斷實例的原型鏈中是否存在某個構造函數的原型。

      原型鏈雖然很強大,但是它也存在一些問題。第一個問題是原型對象上的引用類型值是所有實例共享的,這意味著不同實例的引用類型屬性或方法都指向同一個堆內存,一個實例在原型上修改引用值會同時影響到所有其它實例在原型對象上的該引用值,這便是為何要在構造函數中定義私有屬性或方法,而不是在原型上定義的原因。原型鏈的第二個問題,在于當我們將一個構造函數的原型prototype等于另一個構造函數的實例時,如果我們在這時候給另一個構造函數傳遞參數設置屬性值,那么基于原來的構造函數所有實例的該屬性都會因為原型鏈的關系跟著被賦予相同的值,而這有時候并不是我們想要的結果。

      閉包

      閉包是JavaScript最強大的特性之一,在JavaScript中,閉包,是指有權訪問另一個函數作用域中的變量的函數,它意味著函數可以訪問局部作用域之外的數據。創(chuàng)建閉包的常見方式,就是在一個函數內部創(chuàng)建另一個函數并返回這個函數。

      深入理解JS數據類型、預編譯、執(zhí)行上下文等JS底層機制

      深入理解JS數據類型、預編譯、執(zhí)行上下文等JS底層機制

      一般來講,當函數執(zhí)行完畢后,局部活動對象就會被銷毀,內存中僅保存全局作用域。但是,閉包的情況有所不同。

      深入理解JS數據類型、預編譯、執(zhí)行上下文等JS底層機制

      深入理解JS數據類型、預編譯、執(zhí)行上下文等JS底層機制

      閉包函數的[[Scope]]屬性會初始化為包裹它的函數的作用域鏈,所以閉包包含了與執(zhí)行環(huán)境作用域鏈相同的對象的引用。一般來講,函數的活動對象會隨著執(zhí)行環(huán)境一同銷毀。但引入閉包時,由于引用仍然存在于閉包的[[Scope]]屬性中,因此原函數的活動對象無法被銷毀。這意味著閉包函數與非閉包函數相比,需要

      贊(0)
      分享到: 更多 (0)
      網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號