Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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]

like image 269
AngusC Avatar asked Jan 05 '13 06:01

AngusC


People also ask

Do all functions have a prototype property?

A Function object's prototype property is used when the function is used as a constructor with the new operator. It will become the new object's prototype. Note: Not all Function objects have the prototype property — see description.

Do only functions have prototypes?

Default F.Every function has the "prototype" property even if we don't supply it. The default "prototype" is an object with the only property constructor that points back to the function itself. We can use constructor property to create a new object using the same constructor as the existing one.

Which object in JavaScript does not have a prototype?

Both objectOne and objectTwo are non-function objects therefore they don't have a prototype property.

Why is object prototype undefined?

Only constructor functions have prototypes. Since x is a constructor function, x has a prototype. b is not a constructor function. Hence, it does not have a prototype.


1 Answers

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.

like image 149
Sergiu Dumitriu Avatar answered Sep 27 '22 22:09

Sergiu Dumitriu