20.2 Function Objects

20.2.1 The Function Constructor

The Function constructor:

  • is %Function%.
  • is the initial value of the "Function" property of the global object.
  • creates and initializes a new function object when called as a function rather than as a constructor. Thus the function call Function(…) is equivalent to the object creation expression new Function(…) with the same arguments.
  • is designed to be subclassable. It may be used as the value of an extends clause of a class definition. Subclass constructors that intend to inherit the specified Function behaviour must include a super call to the Function constructor to create and initialize a subclass instance with the internal slots necessary for built-in function behaviour. All ECMAScript syntactic forms for defining function objects create instances of Function. There is no syntactic means to create instances of Function subclasses except for the built-in GeneratorFunction, AsyncFunction, and AsyncGeneratorFunction subclasses.

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

The last argument specifies the body (executable code) of a function; any preceding arguments specify formal parameters.

When the Function function is called with some arguments p1, p2, … , pn, body (where n might be 0, that is, there are no “ p ” arguments, and where body might also not be provided), the following steps are taken:

  1. Let C be the active function object.
  2. Let args be the argumentsList that was passed to this function by [[Call]] or [[Construct]].
  3. Return ? CreateDynamicFunction(C, NewTarget, normal, args).
Note

It is permissible but not necessary to have one argument for each formal parameter to be specified. For example, all three of the following expressions produce the same result:

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")

20.2.1.1.1 CreateDynamicFunction ( constructor, newTarget, kind, args )

The abstract operation CreateDynamicFunction takes arguments constructor (a constructor), newTarget (a constructor), kind (either normal, generator, async, or asyncGenerator), and args (a List of ECMAScript language values). constructor is the constructor function that is performing this action. newTarget is the constructor that new was initially applied to. args is the argument values that were passed to constructor. It performs the following steps when called:

  1. Assert: The execution context stack has at least two elements.
  2. Let callerContext be the second to top element of the execution context stack.
  3. Let callerRealm be callerContext's Realm.
  4. Let calleeRealm be the current Realm Record.
  5. Perform ? HostEnsureCanCompileStrings(callerRealm, calleeRealm).
  6. If newTarget is undefined, set newTarget to constructor.
  7. If kind is normal, then
    1. Let goal be the grammar symbol FunctionBody[~Yield, ~Await].
    2. Let parameterGoal be the grammar symbol FormalParameters[~Yield, ~Await].
    3. Let fallbackProto be "%Function.prototype%".
  8. Else if kind is generator, then
    1. Let goal be the grammar symbol GeneratorBody.
    2. Let parameterGoal be the grammar symbol FormalParameters[+Yield, ~Await].
    3. Let fallbackProto be "%GeneratorFunction.prototype%".
  9. Else if kind is async, then
    1. Let goal be the grammar symbol AsyncFunctionBody.
    2. Let parameterGoal be the grammar symbol FormalParameters[~Yield, +Await].
    3. Let fallbackProto be "%AsyncFunction.prototype%".
  10. Else,
    1. Assert: kind is asyncGenerator.
    2. Let goal be the grammar symbol AsyncGeneratorBody.
    3. Let parameterGoal be the grammar symbol FormalParameters[+Yield, +Await].
    4. Let fallbackProto be "%AsyncGeneratorFunction.prototype%".
  11. Let argCount be the number of elements in args.
  12. Let P be the empty String.
  13. If argCount = 0, let bodyArg be the empty String.
  14. Else if argCount = 1, let bodyArg be args[0].
  15. Else,
    1. Assert: argCount > 1.
    2. Let firstArg be args[0].
    3. Set P to ? ToString(firstArg).
    4. Let k be 1.
    5. Repeat, while k < argCount - 1,
      1. Let nextArg be args[k].
      2. Let nextArgString be ? ToString(nextArg).
      3. Set P to the string-concatenation of P, "," (a comma), and nextArgString.
      4. Set k to k + 1.
    6. Let bodyArg be args[k].
  16. Let bodyString be the string-concatenation of 0x000A (LINE FEED), ? ToString(bodyArg), and 0x000A (LINE FEED).
  17. Let prefix be the prefix associated with kind in Table 50.
  18. Let sourceString be the string-concatenation of prefix, " anonymous(", P, 0x000A (LINE FEED), ") {", bodyString, and "}".
  19. Let sourceText be ! StringToCodePoints(sourceString).
  20. Perform the following substeps in an implementation-defined order, possibly interleaving parsing and error detection:
    1. Let parameters be ParseText(! StringToCodePoints(P), parameterGoal).
    2. If parameters is a List of errors, throw a SyntaxError exception.
    3. Let body be ParseText(! StringToCodePoints(bodyString), goal).
    4. If body is a List of errors, throw a SyntaxError exception.
    5. Let strict be FunctionBodyContainsUseStrict of body.
    6. If strict is true, apply the early error rules for UniqueFormalParameters : FormalParameters to parameters.
    7. If strict is true and IsSimpleParameterList of parameters is false, throw a SyntaxError exception.
    8. If any element of the BoundNames of parameters also occurs in the LexicallyDeclaredNames of body, throw a SyntaxError exception.
    9. If body Contains SuperCall is true, throw a SyntaxError exception.
    10. If parameters Contains SuperCall is true, throw a SyntaxError exception.
    11. If body Contains SuperProperty is true, throw a SyntaxError exception.
    12. If parameters Contains SuperProperty is true, throw a SyntaxError exception.
    13. If kind is generator or asyncGenerator, then
      1. If parameters Contains YieldExpression is true, throw a SyntaxError exception.
    14. If kind is async or asyncGenerator, then
      1. If parameters Contains AwaitExpression is true, throw a SyntaxError exception.
    15. If strict is true, then
      1. If BoundNames of parameters contains any duplicate elements, throw a SyntaxError exception.
  21. Let proto be ? GetPrototypeFromConstructor(newTarget, fallbackProto).
  22. Let realmF be the current Realm Record.
  23. Let scope be realmF.[[GlobalEnv]].
  24. Let F be ! OrdinaryFunctionCreate(proto, sourceText, parameters, body, non-lexical-this, scope).
  25. Perform SetFunctionName(F, "anonymous").
  26. If kind is generator, then
    1. Let prototype be ! OrdinaryObjectCreate(%GeneratorFunction.prototype.prototype%).
    2. Perform DefinePropertyOrThrow(F, "prototype", PropertyDescriptor { [[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }).
  27. Else if kind is asyncGenerator, then
    1. Let prototype be ! OrdinaryObjectCreate(%AsyncGeneratorFunction.prototype.prototype%).
    2. Perform DefinePropertyOrThrow(F, "prototype", PropertyDescriptor { [[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }).
  28. Else if kind is normal, perform MakeConstructor(F).
  29. NOTE: Functions whose kind is async are not constructible and do not have a [[Construct]] internal method or a "prototype" property.
  30. Return F.
Note

CreateDynamicFunction defines a "prototype" property on any function it creates whose kind is not async to provide for the possibility that the function will be used as a constructor.

Table 50: Dynamic Function SourceText Prefixes
KindPrefix
normal"function"
generator"function*"
async"async function"
asyncGenerator"async function*"

20.2.2 Properties of the Function Constructor

The Function constructor:

20.2.2.1 Function.length

This is a data property with a value of 1. This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

20.2.2.2 Function.prototype

The value of Function.prototype is the Function prototype object.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

20.2.3 Properties of the Function Prototype Object

The Function prototype object:

  • is %Function.prototype%.
  • is itself a built-in function object.
  • accepts any arguments and returns undefined when invoked.
  • does not have a [[Construct]] internal method; it cannot be used as a constructor with the new operator.
  • has a [[Prototype]] internal slot whose value is %Object.prototype%.
  • does not have a "prototype" property.
  • has a "length" property whose value is +0𝔽.
  • has a "name" property whose value is the empty String.
Note

The Function prototype object is specified to be a function object to ensure compatibility with ECMAScript code that was created prior to the ECMAScript 2015 specification.

20.2.3.1 Function.prototype.apply ( thisArg, argArray )

When the apply method is called with arguments thisArg and argArray, the following steps are taken:

  1. Let func be the this value.
  2. If IsCallable(func) is false, throw a TypeError exception.
  3. If argArray is undefined or null, then
    1. Perform PrepareForTailCall().
    2. Return ? Call(func, thisArg).
  4. Let argList be ? CreateListFromArrayLike(argArray).
  5. Perform PrepareForTailCall().
  6. Return ? Call(func, thisArg, argList).
Note 1

The thisArg value is passed without modification as the this value. This is a change from Edition 3, where an undefined or null thisArg is replaced with the global object and ToObject is applied to all other values and that result is passed as the this value. Even though the thisArg is passed without modification, non-strict functions still perform these transformations upon entry to the function.

Note 2

If func is an arrow function or a bound function exotic object then the thisArg will be ignored by the function [[Call]] in step 6.

20.2.3.2 Function.prototype.bind ( thisArg, ...args )

When the bind method is called with argument thisArg and zero or more args, it performs the following steps:

  1. Let Target be the this value.
  2. If IsCallable(Target) is false, throw a TypeError exception.
  3. Let F be ? BoundFunctionCreate(Target, thisArg, args).
  4. Let L be 0.
  5. Let targetHasLength be ? HasOwnProperty(Target, "length").
  6. If targetHasLength is true, then
    1. Let targetLen be ? Get(Target, "length").
    2. If Type(targetLen) is Number, then
      1. If targetLen is +∞𝔽, set L to +∞.
      2. Else if targetLen is -∞𝔽, set L to 0.
      3. Else,
        1. Let targetLenAsInt be ! ToIntegerOrInfinity(targetLen).
        2. Assert: targetLenAsInt is finite.
        3. Let argCount be the number of elements in args.
        4. Set L to max(targetLenAsInt - argCount, 0).
  7. Perform ! SetFunctionLength(F, L).
  8. Let targetName be ? Get(Target, "name").
  9. If Type(targetName) is not String, set targetName to the empty String.
  10. Perform SetFunctionName(F, targetName, "bound").
  11. Return F.
Note 1

Function objects created using Function.prototype.bind are exotic objects. They also do not have a "prototype" property.

Note 2

If Target is an arrow function or a bound function exotic object then the thisArg passed to this method will not be used by subsequent calls to F.

20.2.3.3 Function.prototype.call ( thisArg, ...args )

When the call method is called with argument thisArg and zero or more args, the following steps are taken:

  1. Let func be the this value.
  2. If IsCallable(func) is false, throw a TypeError exception.
  3. Perform PrepareForTailCall().
  4. Return ? Call(func, thisArg, args).
Note 1

The thisArg value is passed without modification as the this value. This is a change from Edition 3, where an undefined or null thisArg is replaced with the global object and ToObject is applied to all other values and that result is passed as the this value. Even though the thisArg is passed without modification, non-strict functions still perform these transformations upon entry to the function.

Note 2

If func is an arrow function or a bound function exotic object then the thisArg will be ignored by the function [[Call]] in step 4.

20.2.3.4 Function.prototype.constructor

The initial value of Function.prototype.constructor is %Function%.

20.2.3.5 Function.prototype.toString ( )

When the toString method is called, the following steps are taken:

  1. Let func be the this value.
  2. If Type(func) is Object and func has a [[SourceText]] internal slot and func.[[SourceText]] is a sequence of Unicode code points and ! HostHasSourceTextAvailable(func) is true, then
    1. Return ! CodePointsToString(func.[[SourceText]]).
  3. If func is a built-in function object, return an implementation-defined String source code representation of func. The representation must have the syntax of a NativeFunction. Additionally, if func has an [[InitialName]] internal slot and func.[[InitialName]] is a String, the portion of the returned String that would be matched by NativeFunctionAccessoropt PropertyName must be the value of func.[[InitialName]].
  4. If Type(func) is Object and IsCallable(func) is true, return an implementation-defined String source code representation of func. The representation must have the syntax of a NativeFunction.
  5. Throw a TypeError exception.
NativeFunction : function NativeFunctionAccessoropt PropertyName[~Yield, ~Await]opt ( FormalParameters[~Yield, ~Await] ) { [ native code ] } NativeFunctionAccessor : get set

20.2.3.6 Function.prototype [ @@hasInstance ] ( V )

When the @@hasInstance method of an object F is called with value V, the following steps are taken:

  1. Let F be the this value.
  2. Return ? OrdinaryHasInstance(F, V).

The value of the "name" property of this function is "[Symbol.hasInstance]".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

Note

This is the default implementation of @@hasInstance that most functions inherit. @@hasInstance is called by the instanceof operator to determine whether a value is an instance of a specific constructor. An expression such as

v instanceof F

evaluates as

F[@@hasInstance](v)

A constructor function can control which objects are recognized as its instances by instanceof by exposing a different @@hasInstance method on the function.

This property is non-writable and non-configurable to prevent tampering that could be used to globally expose the target function of a bound function.

20.2.4 Function Instances

Every Function instance is an ECMAScript function object and has the internal slots listed in Table 29. Function objects created using the Function.prototype.bind method (20.2.3.2) have the internal slots listed in Table 30.

Function instances have the following properties:

20.2.4.1 length

The value of the "length" property is an integral Number that indicates the typical number of arguments expected by the function. However, the language permits the function to be invoked with some other number of arguments. The behaviour of a function when invoked on a number of arguments other than the number specified by its "length" property depends on the function. This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

20.2.4.2 name

The value of the "name" property is a String that is descriptive of the function. The name has no semantic significance but is typically a variable or property name that is used to refer to the function at its point of definition in ECMAScript code. This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

Anonymous functions objects that do not have a contextual name associated with them by this specification use the empty String as the value of the "name" property.

20.2.4.3 prototype

Function instances that can be used as a constructor have a "prototype" property. Whenever such a Function instance is created another ordinary object is also created and is the initial value of the function's "prototype" property. Unless otherwise specified, the value of the "prototype" property is used to initialize the [[Prototype]] internal slot of the object created when that function is invoked as a constructor.

This property has the attributes { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }.

Note

Function objects created using Function.prototype.bind, or by evaluating a MethodDefinition (that is not a GeneratorMethod or AsyncGeneratorMethod) or an ArrowFunction do not have a "prototype" property.

20.2.5 HostHasSourceTextAvailable ( func )

The host-defined abstract operation HostHasSourceTextAvailable takes argument func (a function object). It allows host environments to prevent the source text from being provided for func.

An implementation of HostHasSourceTextAvailable must complete normally in all cases. This operation must be deterministic with respect to its parameters. Each time it is called with a specific func as its argument, it must return the same completion record. The default implementation of HostHasSourceTextAvailable is to unconditionally return a normal completion with a value of true.