Function 對象

2018-06-16 15:27 更新

作為函數(shù)調(diào)用 Function 構(gòu)造器

 當(dāng)將 Function 作為函數(shù)來調(diào)用,而不是作為構(gòu)造器,它會創(chuàng)建并初始化一個新函數(shù)對象。所以函數(shù)調(diào)用 Function(…) 與用相同參數(shù)的 new Function(…) 表達式創(chuàng)建的對象相同。

Function (p1, p2, … , pn, body)

 當(dāng)以 p1, p2, … , pn, body 作為參數(shù)調(diào)用 Function 函數(shù)(這里的 n 可以是 0,也就是說沒有“p”參數(shù),這時還可以不提供 body),采用如下步驟:

  1. 創(chuàng)建并返回一個新函數(shù)對象,它仿佛是用相同參數(shù)給標(biāo)準(zhǔn)內(nèi)置構(gòu)造器 Function (15.3.2.1). 用一個 new 表達式創(chuàng)建的。

Function 構(gòu)造器

 當(dāng) Function 作為 new 表達式的一部分被調(diào)用時,它是一個構(gòu)造器:它初始化新創(chuàng)建的對象。

new Function (p1, p2, … , pn, body)

 最后一個參數(shù)指定為函數(shù)的 body( 可執(zhí)行代碼 );之前的任何參數(shù)都指定為形式參數(shù)。

 當(dāng)以 p1, p2, … , pn, body 作為參數(shù)調(diào)用 Function 構(gòu)造器(這里的 n 可以是 0,也就是說沒有“p”參數(shù),這時還可以不提供 body),采用如下步驟:

  1. 令 argCount 為傳給這個函數(shù)調(diào)用的參數(shù)總數(shù) .
  2. 令 P 為空字符串 .
  3. 如果 argCount = 0, 令 body 為空字符串 .
  4. 否則如果 argCount = 1, 令 body 為那個參數(shù) .
  5. 否則 , argCount > 1令 firstArg 為第一個參數(shù) .令 P 為 ToString(firstArg).令 k 為 2.只要 k < argCount 就重復(fù)令 nextArg 為第 k 個參數(shù) .令 P 為之前的 P 值,字符串 ","(一個逗號),ToString(nextArg) 串聯(lián)的結(jié)果。k 遞增 1.令 body 為第 k 個參數(shù) .
  6. 令 body 為 ToString(body).
  7. 如果 P 不可解析為一個 FormalParameterListopt,則拋出一個 SyntaxError 異常 .
  8. 如果 body 不可解析為 FunctionBody,則拋出一個 SyntaxError 異常 .
  9. 如果 body 是嚴(yán)格模式代碼 ( 見 10.1.1),則令 strict 為 true, 否則令 strict 為 false.
  10. 如果 strict 是 true, 適用 13.1 指定拋出的任何異常 .
  11. 返回一個新創(chuàng)建的函數(shù)對象,它是依照 13.2 指定 -- 專遞 P 作為 FormalParameterList,body 作為 FunctionBody,全局環(huán)境作為 Scope 參數(shù),strict 作為嚴(yán)格模式標(biāo)志 -- 創(chuàng)建的。

 每個函數(shù)都會自動創(chuàng)建一個 prototype 屬性,用來支持函數(shù)被當(dāng)做構(gòu)造器使用的可能性。

為每個形參指定一個參數(shù)是允許的,但沒必要。例如以下三個表達式產(chǎn)生相同的結(jié)果:

new Function("a", "b", "c", "return a+b+c") new Function("a, b, c", "return a+b+c") new Function("a,b", "c", "return a+b+c")

Function 構(gòu)造器的屬性

 Function 構(gòu)造器自身是個函數(shù)對象,它的 [[Class]] 是 "Function"。Function 構(gòu)造器的 [[Prototype]] 內(nèi)部屬性值是標(biāo)準(zhǔn)內(nèi)置 Function 的 prototype 對象 (15.3.4)。

 Function 構(gòu)造器的 [[Extensible]] 內(nèi)部屬性值是 true.

 Function 構(gòu)造器有如下屬性 :

Function.prototype

 Function.prototype 的初始值是標(biāo)準(zhǔn)內(nèi)置 Function 的 prototype 對象 (15.3.4)。

 此屬性擁有特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

Function.length

 這是個值為 1 的數(shù)據(jù)屬性。此屬性擁有特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

Function 的 prototype 對象的屬性

 Function 的 prototype 對象自身是一個函數(shù)對象 ( 它的 [[Class]] 是 "Function"),調(diào)用這個函數(shù)對象時,接受任何參數(shù)并返回 undefined。

 Function 的 prototype 對象的 [[Prototype]] 內(nèi)部屬性值是標(biāo)準(zhǔn)內(nèi)置 Object 的 prototype 對象 (15.2.4)。Function 的 prototype 對象的 [[Extensible]] 內(nèi)部屬性的初始值是 true。

 Function 的 prototype 對象自身沒有 valueOf 屬性 ; 但是,它從 Object 的 prototype 對象繼承了 valueOf 屬性。

 Function 的 prototype 對象的 length 屬性是 0。

Function.prototype.constructor

 Function.prototype.constructor 的初始值是內(nèi)置 Function 構(gòu)造器。

Function.prototype.toString ( )

 此函數(shù)的返回值的表示是依賴于實現(xiàn)的。這個表示包含 FunctionDeclaration 的語法。特別注意,怎樣在這個字符串表示中使用和放置空白,行終結(jié)符,分號是依賴于實現(xiàn)的。

 這個 toString 不是通用的;如果它的 this 值不是一個函數(shù)對象,它會拋出一個 TypeError 異常。因此,它不能當(dāng)做方法來轉(zhuǎn)移到其他類型的對象中。

Function.prototype.apply (thisArg, argArray)

 當(dāng)以 thisArg 和 argArray 為參數(shù)在一個 func 對象上調(diào)用 apply 方法,采用如下步驟:

  1. 如果 IsCallable(func) 是 false, 則拋出一個 TypeError 異常 .
  2. 如果 argArray 是 null 或 undefined, 則返回提供 thisArg 作為 this 值并以空參數(shù)列表調(diào)用 func 的 [[Call]] 內(nèi)部方法的結(jié)果。
  3. 如果 Type(argArray) 不是 Object, 則拋出一個 TypeError 異常 .
  4. 令 len 為以 "length" 作為參數(shù)調(diào)用 argArray 的 [[Get]] 內(nèi)部方法的結(jié)果。
  5. 令 n 為 ToUint32(len).
  6. 令 argList 為一個空列表 .
  7. 令 index 為 0.
  8. 只要 index < n 就重復(fù)令 indexName 為 ToString(index).令 nextArg 為以 indexName 作為參數(shù)調(diào)用 argArray 的 [[Get]] 內(nèi)部方法的結(jié)果。將 nextArg 作為最后一個元素插入到 argList 里。設(shè)定 index 為 index + 1.
  9. 提供 thisArg 作為 this 值并以 argList 作為參數(shù)列表,調(diào)用 func 的 [[Call]] 內(nèi)部方法,返回結(jié)果。

 apply 方法的 length 屬性是 2。

 在外面?zhèn)魅氲?thisArg 值會修改并成為 this 值。thisArg 是 undefined 或 null 時它會被替換成全局對象,所有其他值會被應(yīng)用 ToObject 并將結(jié)果作為 this 值,這是第三版引入的更改。

Function.prototype.call (thisArg [ , arg1 [ , arg2, … ] ] )

 當(dāng)以 thisArg 和可選的 arg1, arg2 等等作為參數(shù)在一個 func 對象上調(diào)用 call 方法,采用如下步驟:

  1. 如果 IsCallable(func) 是 false, 則拋出一個 TypeError 異常。
  2. 令 argList 為一個空列表。
  3. 如果調(diào)用這個方法的參數(shù)多余一個,則從 arg1 開始以從左到右的順序?qū)⒚總€參數(shù)插入為 argList 的最后一個元素。
  4. 提供 thisArg 作為 this 值并以 argList 作為參數(shù)列表,調(diào)用 func 的 [[Call]] 內(nèi)部方法,返回結(jié)果。

 call 方法的 length 屬性是 1。

 在外面?zhèn)魅氲?thisArg 值會修改并成為 this 值。thisArg 是 undefined 或 null 時它會被替換成全局對象,所有其他值會被應(yīng)用 ToObject 并將結(jié)果作為 this 值,這是第三版引入的更改。

Function.prototype.bind (thisArg [, arg1 [, arg2, …]])

 bind 方法需要一個或更多參數(shù),thisArg 和(可選的)arg1, arg2, 等等,執(zhí)行如下步驟返回一個新函數(shù)對象:

  1. 令 Target 為 this 值 .
  2. 如果 IsCallable(Target) 是 false, 拋出一個 TypeError 異常 .
  3. 令 A 為一個(可能為空的)新內(nèi)部列表,它包含按順序的 thisArg 后面的所有參數(shù)(arg1, arg2 等等)。
  4. 令 F 為一個新原生 ECMAScript 對象。
  5. 依照 8.12 指定,設(shè)定 F 的除了 [[Get]] 之外的所有內(nèi)部方法。
  6. 依照 15.3.5.4 指定,設(shè)定 F 的 [[Get]] 內(nèi)部屬性。
  7. 設(shè)定 F 的 [[TargetFunction]] 內(nèi)部屬性為 Target。
  8. 設(shè)定 F 的 [[BoundThis]] 內(nèi)部屬性為 thisArg 的值。
  9. 設(shè)定 F 的 [[BoundArgs]] 內(nèi)部屬性為 A。
  10. 設(shè)定 F 的 [[Class]] 內(nèi)部屬性為 "Function"。
  11. 設(shè)定 F 的 [[Prototype]] 內(nèi)部屬性為 15.3.3.1 指定的標(biāo)準(zhǔn)內(nèi)置 Function 的 prototype 對象。
  12. 依照 15.3.4.5.1 描述,設(shè)定 F 的 [[Call]] 內(nèi)置屬性。
  13. 依照 15.3.4.5.2 描述,設(shè)定 F 的 [[Construct]] 內(nèi)置屬性。
  14. 依照 15.3.4.5.3 描述,設(shè)定 F 的 [[HasInstance]] 內(nèi)置屬性。
  15. 如果 Target 的 [[Class]] 內(nèi)部屬性是 "Function", 則令 L 為 Target 的 length 屬性減 A 的長度。設(shè)定 F 的 length 自身屬性為 0 和 L 中更大的值。
  16. 否則設(shè)定 F 的 length 自身屬性為 0.
  17. 設(shè)定 F 的 length 自身屬性的特性為 15.3.5.1 指定的值。
  18. 設(shè)定 F 的 [[Extensible]] 內(nèi)部屬性為 true。
  19. 令 thrower 為 [[ThrowTypeError]] 函數(shù)對象 (13.2.3)。
  20. 以 "caller", 屬性描述符 {[[Get]]: thrower, [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: false}, 和 false 作為參數(shù)調(diào)用 F 的 [[DefineOwnProperty]] 內(nèi)部方法。
  21. 以 "arguments", 屬性描述符 {[[Get]]: thrower, [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: false}, 和 false 作為參數(shù)調(diào)用 F 的 [[DefineOwnProperty]] 內(nèi)部方法。
  22. 返回 F.

 bind 方法的 length 屬性是 1。

 Function.prototype.bind 創(chuàng)建的函數(shù)對象不包含 prototype 屬性或 [[Code]], [[FormalParameters]], [[Scope]] 內(nèi)部屬性。

[[Call]]

 當(dāng)調(diào)用一個用 bind 函數(shù)創(chuàng)建的函數(shù)對象 F 的 [[Call]] 內(nèi)部方法,傳入一個 this 值和一個參數(shù)列表 ExtraArgs,采用如下步驟:

  1. 令 boundArgs 為 F 的 [[BoundArgs]] 內(nèi)部屬性值。
  2. 令 boundThis 為 F 的 [[BoundThis]] 內(nèi)部屬性值。
  3. 令 target 為 F 的 [[TargetFunction]] 內(nèi)部屬性值。
  4. 令 args 為一個新列表,它包含與列表 boundArgs 相同順序相同值,后面跟著與 ExtraArgs 是相同順序相同值。
  5. 提供 boundThis 作為 this 值,提供 args 為參數(shù)調(diào)用 target 的 [[Call]] 內(nèi)部方法,返回結(jié)果。
[[Construct]]

 當(dāng)調(diào)用一個用 bind 函數(shù)創(chuàng)建的函數(shù)對象 F 的 [[Construct]] 內(nèi)部方法,傳入一個參數(shù)列表 ExtraArgs,采用如下步驟:

  1. 令 target 為 F 的 [[TargetFunction]] 內(nèi)部屬性值。
  2. 如果 target 不包含 [[Construct]] 內(nèi)部方法 , 拋出一個 TypeError 異常。
  3. 令 boundArgs 為 F 的 [[BoundArgs]] 內(nèi)部屬性值。
  4. 令 args 為一個新列表,它包含與列表 boundArgs 相同順序相同值,后面跟著與 ExtraArgs 是相同順序相同值。
  5. 提供 args 為參數(shù)調(diào)用 target 的 [[Construct]] 內(nèi)部方法,返回結(jié)果。
[[HasInstance]] (V)

 當(dāng)調(diào)用一個用 bind 函數(shù)創(chuàng)建的函數(shù)對象 F 的 [[Construct]] 內(nèi)部方法,并以 V 作為參數(shù),采用如下步驟:

  1. 令 target 為 F 的 [[TargetFunction]] 內(nèi)部屬性值。
  2. 如果 target 不包含 [[HasInstance]] 內(nèi)部方法 , 拋出一個 TypeError 異常。
  3. 提供 V 為參數(shù)調(diào)用 target 的 [[HasInstance]] 內(nèi)部方法,返回結(jié)果。

Function 的實例的屬性

 除了必要的內(nèi)部屬性之外,每個函數(shù)實例還有一個 [[Call]] 內(nèi)部屬性并且在大多數(shù)情況下使用不同版本的 [[Get]] 內(nèi)部屬性。函數(shù)實例根據(jù)怎樣創(chuàng)建的(見 8.6.2 ,13.2, 15, 15.3.4.5)可能還有一個 [[HasInstance]] 內(nèi)部屬性 , 一個 [[Scope]] 內(nèi)部屬性 , 一個 [[Construct]] 內(nèi)部屬性 , 一個 [[FormalParameters]] 內(nèi)部屬性 , 一個 [[Code]] 內(nèi)部屬性 , 一個 [[TargetFunction]] 內(nèi)部屬性 , 一個 [[BoundThis]] 內(nèi)部屬性 , 一個 [[BoundArgs]] 內(nèi)部屬性。

 [[Class]] 內(nèi)部屬性的值是 "Function"。

 對應(yīng)于嚴(yán)格模式函數(shù) (13.2) 的函數(shù)實例和用 Function.prototype.bind 方法 (15.3.4.5) 創(chuàng)建的函數(shù)實例有名為“caller”和 “arguments”的屬性時,拋出一個 TypeError 異常。一個 ECMAScript 實現(xiàn)不得為在嚴(yán)格模式函數(shù)代碼里訪問這些屬性關(guān)聯(lián)任何依賴實現(xiàn)的特定行為。

length

 length 屬性值是個整數(shù),它指出函數(shù)預(yù)期的“一般的”參數(shù)個數(shù)。然而,語言允許用其他數(shù)量的參數(shù)來調(diào)用函數(shù)。當(dāng)以與函數(shù)的 length 屬性指定的數(shù)量不同的參數(shù)個數(shù)調(diào)用函數(shù)時,它的行為依賴于函數(shù)自身。這個屬性擁有特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

prototype

 prototype 屬性的值用于初始化一個新創(chuàng)建對象的的 [[Prototype]] 內(nèi)部屬性,為了這個新創(chuàng)建對象要先將函數(shù)對象作為構(gòu)造器調(diào)用。這個屬性擁有特性 { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }。

 用 Function.prototype.bind 創(chuàng)建的函數(shù)對象沒有 prototype 屬性。

[[HasInstance]] (V)

 設(shè) F 是個函數(shù)對象。

 當(dāng)以 V 作為參數(shù)調(diào)用 F 的 [[HasInstance]] 內(nèi)部方法,采用如下步驟:

  1. 如果 V 不是個對象 , 返回 false。
  2. 令 O 為用屬性名 "prototype" 調(diào)用 F 的 [[Get]] 內(nèi)部方法的結(jié)果。
  3. 如果 Type(O) 不是 Object, 拋出一個 TypeError 異常。
  4. 重復(fù)令 V 為 V 的 [[Prototype]] 內(nèi)部屬性值。如果 V 是 null, 返回 false.如果 O 和 V 指向相同對象,返回 true。

 用 Function.prototype.bind 創(chuàng)建的函數(shù)對象擁有的不同的 [[HasInstance]] 實現(xiàn),在 15.3.4.5.3 中定義。

[[Get]] (P)

 函數(shù)對象與其他原生 EMACScript 對象 (8.12.3) 用不同的 [[Get]] 內(nèi)部方法。

 設(shè) F 是一個函數(shù)對象,當(dāng)以屬性名 P 調(diào)用 F 的 [[Get]] 內(nèi)部方法 , 采用如下步驟:

  1. 令 v 為傳入 P 作為屬性名參數(shù)調(diào)用 F 的默認(rèn) [[Get]] 內(nèi)部方法 (8.12.3) 的結(jié)果。
  2. 如果 P 是 "caller" 并且 v 是個嚴(yán)格模式函數(shù)對象 , 拋出一個 TypeError 異常。
  3. 返回 v。

 用 Function.prototype.bind 創(chuàng)建的函數(shù)對象使用默認(rèn)的 [[Get]] 內(nèi)部方法。


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號