简体   繁体   中英

Why do built-in functions not have a prototype property?

Given that the ES 5.1 standard states that...

1) Note at the foot of http://es5.github.com/#x13.2

NOTE A prototype property is automatically created for every function,
to allow for the possibility that the function will be used as a constructor.

2) http://es5.github.com/#x15.3.5.2

NOTE Function objects created using Function.prototype.bind do not have
a prototype property.

(which implies that all other functions do)

...why do built-in functions no longer have a prototype property?:

[].push.prototype; //undefined
Math.max.prototype; //undefined

Moreover these built-ins cannot be used as constructors even when they are assigned a prototype property:

[].push.prototype = {};
[].push.prototype; //[object Object]
new [].push(); //TypeError: function push() { [native code] } is not a constructor

Conversely, removing the prototype property from a user defined object still allows it to be used as a constructor, and in fact assigns a generic object to the [[prototype]] of the generated instances:

var A = function() {};
A.prototype = undefined;
A.prototype; //undefined
(new A()).__proto__; //[object Object]

Are built in functions now sub-typed as either constructors or functions?

[Tested in most modern browsers]

It's not the .prototype that allows a function to be used as a constructor, but the presence of the [[Construct]] internal method. See this section , step 4.

Normal functions created by the user script automatically have this internal property set, so all user functions can be called as constructors. This is because the interpreter can't know how the user intends to use that method.

For native functions the intended usage is known in advance, so the javascript engine can decide which native functions should be callable as constructors. Does it make sense to invoke new [].push ?

It is mentioned in the introductory part to built-in objects that:

None of the built-in functions described in this clause that are not constructors shall implement the [[Construct]] internal method unless otherwise specified in the description of a particular function. None of the built-in functions described in this clause shall have a prototype property unless otherwise specified in the description of a particular function.

And the reason, IMHO, is that there is no valid real use case that would need that. There's no good explanation why push should be instantiable: what's the difference between a new push and a new generic object? So, allowing the instantiation of those functions doesn't bring any value to the developer, but it will raise lots of WTFs from others reading the code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM