Function 对象

2018-06-16 15:27 更新

作为函数调用 Function 构造器

 当将 Function 作为函数来调用,而不是作为构造器,它会创建并初始化一个新函数对象。所以函数调用 Function(…) 与用相同参数的 new Function(…) 表达式创建的对象相同。

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

 当以 p1, p2, … , pn, body 作为参数调用 Function 函数(这里的 n 可以是 0,也就是说没有“p”参数,这时还可以不提供 body),采用如下步骤:

  1. 创建并返回一个新函数对象,它仿佛是用相同参数给标准内置构造器 Function (15.3.2.1). 用一个 new 表达式创建的。

Function 构造器

 当 Function 作为 new 表达式的一部分被调用时,它是一个构造器:它初始化新创建的对象。

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

 最后一个参数指定为函数的 body( 可执行代码 );之前的任何参数都指定为形式参数。

 当以 p1, p2, … , pn, body 作为参数调用 Function 构造器(这里的 n 可以是 0,也就是说没有“p”参数,这时还可以不提供 body),采用如下步骤:

  1. 令 argCount 为传给这个函数调用的参数总数 .
  2. 令 P 为空字符串 .
  3. 如果 argCount = 0, 令 body 为空字符串 .
  4. 否则如果 argCount = 1, 令 body 为那个参数 .
  5. 否则 , argCount > 1令 firstArg 为第一个参数 .令 P 为 ToString(firstArg).令 k 为 2.只要 k < argCount 就重复令 nextArg 为第 k 个参数 .令 P 为之前的 P 值,字符串 ","(一个逗号),ToString(nextArg) 串联的结果。k 递增 1.令 body 为第 k 个参数 .
  6. 令 body 为 ToString(body).
  7. 如果 P 不可解析为一个 FormalParameterListopt,则抛出一个 SyntaxError 异常 .
  8. 如果 body 不可解析为 FunctionBody,则抛出一个 SyntaxError 异常 .
  9. 如果 body 是严格模式代码 ( 见 10.1.1),则令 strict 为 true, 否则令 strict 为 false.
  10. 如果 strict 是 true, 适用 13.1 指定抛出的任何异常 .
  11. 返回一个新创建的函数对象,它是依照 13.2 指定 -- 专递 P 作为 FormalParameterList,body 作为 FunctionBody,全局环境作为 Scope 参数,strict 作为严格模式标志 -- 创建的。

 每个函数都会自动创建一个 prototype 属性,用来支持函数被当做构造器使用的可能性。

为每个形参指定一个参数是允许的,但没必要。例如以下三个表达式产生相同的结果:

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 构造器的属性

 Function 构造器自身是个函数对象,它的 [[Class]] 是 "Function"。Function 构造器的 [[Prototype]] 内部属性值是标准内置 Function 的 prototype 对象 (15.3.4)。

 Function 构造器的 [[Extensible]] 内部属性值是 true.

 Function 构造器有如下属性 :

Function.prototype

 Function.prototype 的初始值是标准内置 Function 的 prototype 对象 (15.3.4)。

 此属性拥有特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

Function.length

 这是个值为 1 的数据属性。此属性拥有特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

Function 的 prototype 对象的属性

 Function 的 prototype 对象自身是一个函数对象 ( 它的 [[Class]] 是 "Function"),调用这个函数对象时,接受任何参数并返回 undefined。

 Function 的 prototype 对象的 [[Prototype]] 内部属性值是标准内置 Object 的 prototype 对象 (15.2.4)。Function 的 prototype 对象的 [[Extensible]] 内部属性的初始值是 true。

 Function 的 prototype 对象自身没有 valueOf 属性 ; 但是,它从 Object 的 prototype 对象继承了 valueOf 属性。

 Function 的 prototype 对象的 length 属性是 0。

Function.prototype.constructor

 Function.prototype.constructor 的初始值是内置 Function 构造器。

Function.prototype.toString ( )

 此函数的返回值的表示是依赖于实现的。这个表示包含 FunctionDeclaration 的语法。特别注意,怎样在这个字符串表示中使用和放置空白,行终结符,分号是依赖于实现的。

 这个 toString 不是通用的;如果它的 this 值不是一个函数对象,它会抛出一个 TypeError 异常。因此,它不能当做方法来转移到其他类型的对象中。

Function.prototype.apply (thisArg, argArray)

 当以 thisArg 和 argArray 为参数在一个 func 对象上调用 apply 方法,采用如下步骤:

  1. 如果 IsCallable(func) 是 false, 则抛出一个 TypeError 异常 .
  2. 如果 argArray 是 null 或 undefined, 则返回提供 thisArg 作为 this 值并以空参数列表调用 func 的 [[Call]] 内部方法的结果。
  3. 如果 Type(argArray) 不是 Object, 则抛出一个 TypeError 异常 .
  4. 令 len 为以 "length" 作为参数调用 argArray 的 [[Get]] 内部方法的结果。
  5. 令 n 为 ToUint32(len).
  6. 令 argList 为一个空列表 .
  7. 令 index 为 0.
  8. 只要 index < n 就重复令 indexName 为 ToString(index).令 nextArg 为以 indexName 作为参数调用 argArray 的 [[Get]] 内部方法的结果。将 nextArg 作为最后一个元素插入到 argList 里。设定 index 为 index + 1.
  9. 提供 thisArg 作为 this 值并以 argList 作为参数列表,调用 func 的 [[Call]] 内部方法,返回结果。

 apply 方法的 length 属性是 2。

 在外面传入的 thisArg 值会修改并成为 this 值。thisArg 是 undefined 或 null 时它会被替换成全局对象,所有其他值会被应用 ToObject 并将结果作为 this 值,这是第三版引入的更改。

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

 当以 thisArg 和可选的 arg1, arg2 等等作为参数在一个 func 对象上调用 call 方法,采用如下步骤:

  1. 如果 IsCallable(func) 是 false, 则抛出一个 TypeError 异常。
  2. 令 argList 为一个空列表。
  3. 如果调用这个方法的参数多余一个,则从 arg1 开始以从左到右的顺序将每个参数插入为 argList 的最后一个元素。
  4. 提供 thisArg 作为 this 值并以 argList 作为参数列表,调用 func 的 [[Call]] 内部方法,返回结果。

 call 方法的 length 属性是 1。

 在外面传入的 thisArg 值会修改并成为 this 值。thisArg 是 undefined 或 null 时它会被替换成全局对象,所有其他值会被应用 ToObject 并将结果作为 this 值,这是第三版引入的更改。

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

 bind 方法需要一个或更多参数,thisArg 和(可选的)arg1, arg2, 等等,执行如下步骤返回一个新函数对象:

  1. 令 Target 为 this 值 .
  2. 如果 IsCallable(Target) 是 false, 抛出一个 TypeError 异常 .
  3. 令 A 为一个(可能为空的)新内部列表,它包含按顺序的 thisArg 后面的所有参数(arg1, arg2 等等)。
  4. 令 F 为一个新原生 ECMAScript 对象。
  5. 依照 8.12 指定,设定 F 的除了 [[Get]] 之外的所有内部方法。
  6. 依照 15.3.5.4 指定,设定 F 的 [[Get]] 内部属性。
  7. 设定 F 的 [[TargetFunction]] 内部属性为 Target。
  8. 设定 F 的 [[BoundThis]] 内部属性为 thisArg 的值。
  9. 设定 F 的 [[BoundArgs]] 内部属性为 A。
  10. 设定 F 的 [[Class]] 内部属性为 "Function"。
  11. 设定 F 的 [[Prototype]] 内部属性为 15.3.3.1 指定的标准内置 Function 的 prototype 对象。
  12. 依照 15.3.4.5.1 描述,设定 F 的 [[Call]] 内置属性。
  13. 依照 15.3.4.5.2 描述,设定 F 的 [[Construct]] 内置属性。
  14. 依照 15.3.4.5.3 描述,设定 F 的 [[HasInstance]] 内置属性。
  15. 如果 Target 的 [[Class]] 内部属性是 "Function", 则令 L 为 Target 的 length 属性减 A 的长度。设定 F 的 length 自身属性为 0 和 L 中更大的值。
  16. 否则设定 F 的 length 自身属性为 0.
  17. 设定 F 的 length 自身属性的特性为 15.3.5.1 指定的值。
  18. 设定 F 的 [[Extensible]] 内部属性为 true。
  19. 令 thrower 为 [[ThrowTypeError]] 函数对象 (13.2.3)。
  20. 以 "caller", 属性描述符 {[[Get]]: thrower, [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: false}, 和 false 作为参数调用 F 的 [[DefineOwnProperty]] 内部方法。
  21. 以 "arguments", 属性描述符 {[[Get]]: thrower, [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: false}, 和 false 作为参数调用 F 的 [[DefineOwnProperty]] 内部方法。
  22. 返回 F.

 bind 方法的 length 属性是 1。

 Function.prototype.bind 创建的函数对象不包含 prototype 属性或 [[Code]], [[FormalParameters]], [[Scope]] 内部属性。

[[Call]]

 当调用一个用 bind 函数创建的函数对象 F 的 [[Call]] 内部方法,传入一个 this 值和一个参数列表 ExtraArgs,采用如下步骤:

  1. 令 boundArgs 为 F 的 [[BoundArgs]] 内部属性值。
  2. 令 boundThis 为 F 的 [[BoundThis]] 内部属性值。
  3. 令 target 为 F 的 [[TargetFunction]] 内部属性值。
  4. 令 args 为一个新列表,它包含与列表 boundArgs 相同顺序相同值,后面跟着与 ExtraArgs 是相同顺序相同值。
  5. 提供 boundThis 作为 this 值,提供 args 为参数调用 target 的 [[Call]] 内部方法,返回结果。
[[Construct]]

 当调用一个用 bind 函数创建的函数对象 F 的 [[Construct]] 内部方法,传入一个参数列表 ExtraArgs,采用如下步骤:

  1. 令 target 为 F 的 [[TargetFunction]] 内部属性值。
  2. 如果 target 不包含 [[Construct]] 内部方法 , 抛出一个 TypeError 异常。
  3. 令 boundArgs 为 F 的 [[BoundArgs]] 内部属性值。
  4. 令 args 为一个新列表,它包含与列表 boundArgs 相同顺序相同值,后面跟着与 ExtraArgs 是相同顺序相同值。
  5. 提供 args 为参数调用 target 的 [[Construct]] 内部方法,返回结果。
[[HasInstance]] (V)

 当调用一个用 bind 函数创建的函数对象 F 的 [[Construct]] 内部方法,并以 V 作为参数,采用如下步骤:

  1. 令 target 为 F 的 [[TargetFunction]] 内部属性值。
  2. 如果 target 不包含 [[HasInstance]] 内部方法 , 抛出一个 TypeError 异常。
  3. 提供 V 为参数调用 target 的 [[HasInstance]] 内部方法,返回结果。

Function 的实例的属性

 除了必要的内部属性之外,每个函数实例还有一个 [[Call]] 内部属性并且在大多数情况下使用不同版本的 [[Get]] 内部属性。函数实例根据怎样创建的(见 8.6.2 ,13.2, 15, 15.3.4.5)可能还有一个 [[HasInstance]] 内部属性 , 一个 [[Scope]] 内部属性 , 一个 [[Construct]] 内部属性 , 一个 [[FormalParameters]] 内部属性 , 一个 [[Code]] 内部属性 , 一个 [[TargetFunction]] 内部属性 , 一个 [[BoundThis]] 内部属性 , 一个 [[BoundArgs]] 内部属性。

 [[Class]] 内部属性的值是 "Function"。

 对应于严格模式函数 (13.2) 的函数实例和用 Function.prototype.bind 方法 (15.3.4.5) 创建的函数实例有名为“caller”和 “arguments”的属性时,抛出一个 TypeError 异常。一个 ECMAScript 实现不得为在严格模式函数代码里访问这些属性关联任何依赖实现的特定行为。

length

 length 属性值是个整数,它指出函数预期的“一般的”参数个数。然而,语言允许用其他数量的参数来调用函数。当以与函数的 length 属性指定的数量不同的参数个数调用函数时,它的行为依赖于函数自身。这个属性拥有特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

prototype

 prototype 属性的值用于初始化一个新创建对象的的 [[Prototype]] 内部属性,为了这个新创建对象要先将函数对象作为构造器调用。这个属性拥有特性 { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }。

 用 Function.prototype.bind 创建的函数对象没有 prototype 属性。

[[HasInstance]] (V)

 设 F 是个函数对象。

 当以 V 作为参数调用 F 的 [[HasInstance]] 内部方法,采用如下步骤:

  1. 如果 V 不是个对象 , 返回 false。
  2. 令 O 为用属性名 "prototype" 调用 F 的 [[Get]] 内部方法的结果。
  3. 如果 Type(O) 不是 Object, 抛出一个 TypeError 异常。
  4. 重复令 V 为 V 的 [[Prototype]] 内部属性值。如果 V 是 null, 返回 false.如果 O 和 V 指向相同对象,返回 true。

 用 Function.prototype.bind 创建的函数对象拥有的不同的 [[HasInstance]] 实现,在 15.3.4.5.3 中定义。

[[Get]] (P)

 函数对象与其他原生 EMACScript 对象 (8.12.3) 用不同的 [[Get]] 内部方法。

 设 F 是一个函数对象,当以属性名 P 调用 F 的 [[Get]] 内部方法 , 采用如下步骤:

  1. 令 v 为传入 P 作为属性名参数调用 F 的默认 [[Get]] 内部方法 (8.12.3) 的结果。
  2. 如果 P 是 "caller" 并且 v 是个严格模式函数对象 , 抛出一个 TypeError 异常。
  3. 返回 v。

 用 Function.prototype.bind 创建的函数对象使用默认的 [[Get]] 内部方法。


以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号