Are Array, Object, Map built-in constructor functions or classes? - javascript

In some places, they say that Array, Date and Object are built-in classes. However, I find that they can all be called without new which isn't supposed to be possible with classes.
And even though Map, Set, etc... can't be called without new. All of them will show something like function ItsName() { [native code] } while trying to get their definition while I would think a class is supposed to show something like class ItsName { [native code] }.

The most specific description for objects like Object, Array, etc. is "built-in constructor".
In short, section 4.4.12 built-in object annotates:
NOTE
Standard built-in objects are defined in this specification.
An ECMAScript implementation may specify and supply additional kinds of
built-in objects. A built-in constructor is a built-in object that is
also a constructor.
Section 4 is non-normative, but the above note can be derived from the following:
Section 6.1.7.2 Object Internal Methods and Internal Slots: (Boldness applied by me)
... A function object is an object that supports
the [[Call]] internal method. A constructor is an object that
supports the [[Construct]] internal method. Every object that
supports [[Construct]] must support [[Call]];
that is, every constructor must be a function object.
Therefore, a constructor may also be referred to as a
constructor function or constructor function object.
This means, constructors are functions, and functions are objects.
Section 6.1.7.4 Well-Known Intrinsic Objects:
Well-known intrinsics are built-in objects (...).
And:
The well-known intrinsics are listed in Table 6.
With Table 6:
Global Name
ECMAScript Language Association
Array
The Array constructor (23.1.1)
Object
The Object constructor (20.1.1)
...
...
Point 2 lists several built-in objects like Array and Object. The table and the definitions in the corresponding links call these "constructors".
Point 1 explains that constructors are objects, so it is valid to say "built-in constructor" instead of "built-in objects", where applicable.
Here is a short summary of other interesting terms and definitions in the specification:
An object is a member of the type Object. (See 4.4.6)
A function (or function object) is an object that supports the internal function [[Call]] (which may or may not be exposed). (See 6.1.7.2 Table 5)
A constructor (or constructor function or constructor function object) is a function that supports the internal function [[Construct]] (commonly invoked with the new operator). (See 6.1.7.2 Table 5)
All constructors have the property prototype. (See 4.3.1)
Both function definitions and function expressions create constructors. (See 15.2.4 and 15.2.5, respectively)
Arrow function expressions do not create constructors and can therefore not be instantiated. (See 15.3.4)
Class definitions (ES6 class syntax) return constructor functions that are uncallable (meaning they do not expose [[Call]]). (See 15.7.14)

Related

why typeof(Function.prototype) is function

I am aware of the fact that Prototypes are object literal. So methods and properties can be defined on them. Function.prototype has some method like apply, call, bind, toString etc. So I thought a function's prototype should be a object literal. But I ran following code and encountered that Function.prototype is of type function !
console.log(typeof(Function.prototype)); // function
How come it is not a object literal itself ?
From the specification:
The Function prototype object is the intrinsic object %FunctionPrototype%. The Function prototype object is itself a built-in function object. When invoked, it accepts any arguments and returns undefined. It does not have a [[Construct]] internal method so it is not a constructor.
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.
(my emphasis)
If we go to the ES5 spec, it says:
The Function prototype object is itself a Function object (its [[Class]] is "Function") that, when invoked, accepts any arguments and returns undefined.
...without offering any explanation for why that would be the case. That language is essentially unchanged in ES1, ES2, ES3, and ES5. I think the original idea was basically that that was what gave it its function-ness, although typeof (even in ES1) didn't look at the internal [[Class]], it looked at whether the thing implemented [[Call]] (as it still does). When something goes back all the way to ES1, one frequently has to just invoke the "because Eich did the first JavaScript in 10 days and yeah, weird stuff happens when you do that" argument. :-)
Side note: By "object literal" I take it you mean "plain object." (An "object literal" — what the specifiation calls an object initializer — is just a way to write an object in source code. There are other ways to create plain objects.)
An object literal is some JavaScript syntax for creating objects. It isn't a data type.
Functions are just a specific type of object in JavaScript. Anywhere you can have an object, you can have a function.
Let's say you have declared an array,
let arr = [ 1 , 2 ];
So, internally it will be created as
let arr = new Array ( 1, 2 );
This is the function constructor.
Have you ever thought about how the array got all functions like concate, map, filter, reduce etc.?
Internally when we create an instance from a function constructor, the prototype property of a function will be set to the prototype property of that newly created instance. Hense, this concate, map, filter, reduce get automatically associated with that function constructor. So that's how we can use that array properties by arr.map, arr.concate.
Actually the prototype property of a function is visible but the prototype property of an instance which is created by a function constructor is hidden. If you want to check then you can check it by obj_name.proto. It's a pointer towards that prototype property.
Now, you can see that the array "arr" is not the array internally. It's an instance of a function constructor. That's why if you check the type of the array, you will get the answer as object and also if you check the typeof(Array), you will get the answer as Function.
If you find it useful then please like it on
https://www.linkedin.com/posts/sh-jay_javascript-array-prototype-activity-6951547190049677312-Dqbn?utm_source=linkedin_share&utm_medium=member_desktop_web
Well, I don't think you mean object literal, as alluded to by other answers and comments.
alert(Function.prototype instanceof Object) // true
alert(Function.prototype instanceof Function) // true
alert(typeof Function.prototype) // function
It is an object. It's also a function. Also, all functions are objects. They're all following the rules just fine.
alert((function(){}) instanceof Object) // true
alert((function(){}) instanceof Function) // true
alert(typeof (function(){})) // function
One big happy we-all-derive-from-Object family. Why should the prototype of Function not be a function?
Now if you wanna get weird... let's get weird.
var notAFn = Object.create(Function.prototype);
alert(notAFn instanceof Function); // true
alert(typeof notAFn); // object
And no, you can't call notAFn(). Not until they add a call Symbol for that. :)
Oh hey, feel free to tell me why this isn't a good answer. I'll try to improve it.

Function.prototype is a function

I'm digging into the Javascript prototype chain.
In order to document my findings, I've drawn the following scheme:
Although most of the concepts are clear, I'm left with just two related questions. Rather than splitting them up, I guessed that centralising them in this question might be better:
Is there a reason for Function.prototype to be of type function, instead of object?
typeof Function.prototype; //"function"
Is Function.prototype a 'unique function' in JS since it doesn't have a prototype property of its own like other functions do? (is there a generally accepted 'name' to refer to it?)
The reason is that the ES5 spec says so:
The Function prototype object is itself a Function object (its
[[Class]] is "Function") that, when invoked, accepts any arguments and
returns undefined.
Note it's common in ES5 to make the prototype of some class a member of that class:
Object.prototype is an Object object.
Function.prototype is a Function object which returns undefined when invoked.
Array.prototype is an empty Array object.
String.prototype is a String object whose value is an empty String.
Boolean.prototype is a Boolean object whose value is false.
Number.prototype is a Number object whose value is +0.
Date.prototype is a Date object whose [[PrimitiveValue]] is NaN.
RegExp.prototype is a RegExp object whose data properties are like new RegExp()'s ones.
Error.prototype is an Error object.
I think it was standardized as such because the prototype of a class has the intrinsic properties of that class, as the instances of that class. And if it looks like a duck it should behave as a duck. So calling the methods of the prototype on the prototype itself instead of on an instance should work too.
However, ES6 didn't like this. So it changed the behavior for those:
Boolean.prototype is an ordinary object with no [[BooleanData]] internal slot.
Error.prototype is an ordinary object with no [[ErrorData]] internal slot.
Number.prototype is an ordinary object with no [[NumberData]] internal slot.
Date.prototype is an ordinary object with no [[DateValue]] internal slot.
String.prototype is an ordinary object with no [[StringData]] internal slot.
RegExp.prototype is an ordinary object with no [[RegExpMatcher]] nor any of the other internal slots of RegExp instance objects.
And also for new "classes" (ES6 objects no longer have a [[Class]]):
Symbol.prototype is an ordinary object with no [[SymbolData]] internal slot.
TypedArray.prototype is an ordinary object with no [[ViewedArrayBuffer]] nor any other of the internal slots that are specific to TypedArray instance objects.
Map.prototype is an ordinary object with no [[MapData]] internal slot.
Set.prototype is an ordinary object with no [[SetData]] internal slot.
WeakMap.prototype is an ordinary object with no [[WeakMapData]] internal slot.
WeakSet.prototype is an ordinary object with no [[WeakSetData]] internal slot.
ArrayBuffer.prototype is an ordinary object with no [[ArrayBufferData]] nor [[ArrayBufferByteLength]] internal slots.
DataView.prototype is an ordinary object with no [[DataView]], [[ViewedArrayBuffer]], [[ByteLength]], nor [[ByteOffset]] internal slots.
GeneratorFunction.prototype is an ordinary object with no [[ECMAScriptCode]] nor any other of the internal slots listed in Table 27 or Table 56.
Promise.prototype is an ordinary object with no [[PromiseState]] nor any of the other internal slots of Promise instances.
However, the old behavior remains for those:
Function.prototype is itself a built-in function object.
Array.prototype is an Array exotic object and has the internal methods specified for such objects.
So now the reason is backwards compatibility:
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.
Note this doesn't make Function.prototype a special function. Only constructors have the prototype property:
Function instances that can be used as a constructor have a prototype
property.
There are multiple examples of non-constructor functions apart from Function.prototype, such as
Methods in Math object:
typeof Math.pow; // "function
'prototype' in Math.pow; // false
Some host objects:
typeof document.createElement('object'); // "function
'prototype' in document.createElement('object'); // false
In ES6, arrow functions:
typeof (x => x * x); // "function
'prototype' in (x => x * x); // false
In answer to your questions:
1) Function.prototype is a type of function because, according to ECMAScript 2015:
The Function prototype object is the intrinsic object %FunctionPrototype%. The Function prototype object is itself a built-in function object.
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.
So the Function prototype object is only defined as a Function object to ensure compatability with older ECMAScript standards. The function doesn't actually do anything:
When invoked, it accepts any arguments and returns undefined.
http://www.ecma-international.org/ecma-262/6.0/#sec-properties-of-the-function-prototype-object
2) Regarding the prototype property:
The Function prototype object does not have a prototype property.
Same Source
This is unique since all functions usually possess a prototype property, however since the Function prototype object is only specified as a Function object to maintain compatability, it's behaviour is unlike that of regular functions.
I've created a JSFiddle with various tests in case it helps anyone:
http://jsfiddle.net/Ld0b39xz/
// We'll use 'Object.getPrototypeOf' to access [[prototype]]
// As you know, [[prototype]] of Object.prototype returns 'null'.
console.log(Object.getPrototypeOf(Object.prototype));
// null
////////////////////////////////////////////////////////
// Let's take a closer look at Function.prototype
console.log(Function.prototype);
// Output:
// function(){}
// This is what the specs say should happen:
// "The Function prototype object is itself a built-in function object."
/////////////////////////////////////////////////////
// Let's see if this function has a 'prototype' property.
// All functions normally have a prototype property that initially
// references an empty object...except this one.
var fn = Function.prototype;
console.log(fn.prototype);
// Output:
// undefined
// This is expected, according to the specs:
// "The Function prototype object does not have a prototype property."
// It does have some properties such as 'name' and 'length',
// but not 'prototype'.
////////////////////////////////////////////////////////
// Let's see what [[prototype]] of Function.prototype returns.
console.log(Object.getPrototypeOf(Function.prototype));
// Output:
// Object{}
// Again this is expected:
// "The value of the [[Prototype]] internal slot of the
// Function prototype object is the intrinsic object %ObjectPrototype%"
/////////////////////////////////////////////////////////
// Now lets see what the [[Prototype]] of this object is:
console.log(Object.getPrototypeOf(Object.getPrototypeOf(Function.prototype)));
// Output:
// null
// We've come full circle since all the statement above is
// doing is looking for the prototoype of the native Object,
// which we already know is 'null' from our first test.
In replacement of a previous answer which I could not stand by. With thanks to Oriol. The head scratching is mine.
In regards the first question the Function object it not particularly different simply because Function.prototype is a function. Other built in constructors use prototype objects of their own type. What draws attention to the Function case is that the typeof operator treats function objects diffently to other objects by returning "function" instead of "object".
Global constructors listing themselves as constructors of their prototype objects:
var BuiltIn = Function; // for example
BuiltIn.prototype.constructor == BuiltIn // true
is more or less documentary. Prototype objects of built in constructors generally have methods which interface with the javascript engine and are not created using a javascript call to their listed constructor as it appears at run time: Function.prototype instanceof Function is false with similar results for other built in constructors such as Array, RegExp etc tested.
The global Function object is unique, however, in that it lists itself as is its own constructor (Function.constructor == Function is true), and that it is an instance of itself (Function instanceof Function is true as well). The latter result indicates that Function.prototype is in the prototype chain of Function. Function.prototype itself is prototyped on Object.prototype.
Another reason to think Function.prototype is not a Function object in the usual sense (apart from saying so in the documentation) is that it cannot be called as a constructor and throws an error if an attempt is made to do so. Since the prototype property of a function is used when the function is called as a constructor, it makes sense for Function.prototype not to have this property.

Design: why does JavaScript have separate Function and Object objects, and why do these have their own separate prototype objects? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I've come across the following diagram which looks rather messy.
So here comes my question:
Why does JavaScipt have separate Function and Object function objects
(instead of for instance simply having everything defined at the top level
by the user point to a single prototype object Root, and with the prototype
of Root pointing back to Root, which would seem to be a much simpler
and more intuitive design)?
Thanks.
Sorry for my misunderstanding. Now I realize:
JavaScript has primitive data types and objects. The primitive data types are
boolean, number, string, null, and undefined. When needed the first three of
these are treated as instances of Boolean, Number, and String. Everything
else is an object, including functions, arrays, regular expressions, and
dates. Functions may be used as constructors or as ordinary functions.
When a function is used as a constructor it can be used to instantiate
object instances via the new operator. The prototype of the instantiated
instance (accessed via the __proto__ property) is set to the constructor's
'prototype' property when the instance is instantiated. The __proto__
members are used to resolve properties via the prototypical inheritance chain.
Since functions are more specialized than objects there is a Function.prototype
object stuck in the prototypical inheritance chain between functions and the
top-level Object.prototype object. The Function and Object constructor
functions should themselves not normally be needed since we can make
use of the function keyword and object literals directly.
A constructor function can only have one prototype (at any given time). When an object is constructed, it becomes related to the prototype object referenced by its constructor. Function objects (and String objects and Date objects, etc) have prototypes with different sets of properties. All objects have prototype chains that eventually go back to the Object prototype.
The case with Function instances is even more distinct: the constructed objects are functions. The Function constructor (which is part of the native runtime) gives the constructed object internal properties that make it possible for the runtime to access the block of code associated with functions. Specifically (this is all from section 13.2 of the spec:
The [[Call]] internal property is set to the value of the parsed function body (the code of the function)
The [[Construct]] internal property is also set to the function body (and that's why all functions can be used as constructors)
The [[HasInstance]] internal property is made to refer to the internal code that implements section 15.3.5.3, which makes instanceOf work
and similarly for internal properties [[Code]], [[FormalParameters]], [[Scope]], and others. In other words, a function object is iternally special in a lot of ways. In its relationship to the Function prototype, however, it's not really special. The function prototype is consulted during the process of property lookup on the function object itself. For example, when resolving an expression like this:
var bound = function() { alert(this); }.bind("hello");
the runtime has to locate the property "bind". It won't be found on the function object itself, but it will be found on the prototype.

Is a constructor always a function object?

I'm reading the latest ECMA-262 reference, edition 5.1 June 2011.
In section 8.6.2 table 9 we have in regard to the [[Construct]] internal property:
Creates an object. Invoked via the new operator. The
arguments to the SpecOp are the arguments passed to the
new operator. Objects that implement this internal method
are called constructors.
The standard doesn't say that a constructor has to be a Function object. So can we have a constructor object that is not a function object?
Link to the standard as requested
The answer is extremely simple. ES5 § 4.3.4 says:
Constructor
Function object that creates and initialises objects.
So there you have it, by definition only a Function can be a constructor. However, likely there are host objects that behave like constructors that do not have any of the other attributes of native Function objects (e.g. the original XMLHttpRequest object in IE that was implemented in ActiveX).
While the term "Constructor" is defined (as #RobG pointed out), there is nothing that prevents a non-"Constructor" object from having a [[Construct]] method.
This is a bit confusing. It means you can use the new operator on an object that is not a Function (thus not a "constructor" as per 4.3.4
), but does indeed provide a [[Construct]] method.
Note that none of the standard objects qualify for that, but host objects may indeed. A browser plugin such as Java may expose some object like so:
new java.lang.String(); // it works, so java.lang.String has a [[Construct]] method
java.lang.String instanceof Function // false
Object.prototype.toString.call(java.lang.String).indexOf('Function') // -1
Note that typeof java.lang.String returns "function" even though java.lang.String is not a function. This is correct according to 11.4.3 (it is a host object with a [[Call]] method)
To add to Pumbaa80's answer (this would be too long for a comment).
The confusion is increased by 13.2.2 according to which when a function's construct is executed its call operation has to be executed(but it doesn't say what has to be done when the construct of an object that isn't a function is executed). Now, objects who implement call are callable function objects according to 9.11.
Also according to 4.2 "a function is a callable object". But of course this doesn't imply that every callable object is a function.
So if I got this right non Function objects can have a Construct method and also a Call method. java.lang.String would be one such example.

Every Object is a function and every function is Object - Which is Correct?

I was reading this link JavaScript_syntax
This seems to be cyclic - that every function is an Object and every Object itself is a function. Which is the atomic one? Can someone explain in a better way?
Anything that is not a primitive type (undefined, null, number, string, boolean) is an object (or an instance) in JavaScript. That means function inherits from object.
Object instances can contain more instances which can be functions. That's what we call a "method" (since it has an automatic this variable).
Since you can't "call" every Object instance, not every object is a function.
I think this concept is often misunderstood.
A utility to visualize JS types relationship http://jstype.herokuapp.com/#/home
Javascript Data Types
Primitive types - numbers, strings, booleans, null and undefined.
All non-primitive types are object:
var foo = { };
var foo = [1, 2, 3];
var foo = function abc() { return "hello world"; };
var foo = new Number(30);
var foo = new String("Hello World");
var foo = new Boolean(true);
var foo = new RegExp(/[foo]+/);
// All 'foo` are object.
All primitive types have a corresponding Constructor Function wiz. Array, Number, String, Boolean, RegExp. As all functions are objects, they are objects too. So we can call them Constructor Function Objects.
Most of the non-primitive type has prototype property where all inherited stuff lives. Math doesn't have prototype.
All objects inherit from Object.prototype which inherits from null.
object <- Object.prototype <- null
All native functions inherit from Function.prototype which inherits from Object.prototype.
function <- Function.prototype <- Object.prototype <- null
Arrays inherit from Array.prototype which inherits from Object.prototype.
array <- Array.prototype <- Object.prototype <- null
Must read MDN: Inheritance and prototype chain
To get confused Stackoverflow: prototype in JavaScript
Stack Overflow: Function prototype explained
Every function is an object. Objects can contain functions (methods) but an object is not necessary a function.
Also Function is always a property of an object.
This mean that all functions in JavaScript is always bound to an object. If you don't specify an object to bind a function to it's bound to the window object (Also called global functions)
..fredrik
It would be better to say that in JavaScript everything can be treated as an object, that includes primitive types as well as functions types; what the JavaScript interpreter does is that it automatically promotes your primitives and functions to their object wrapper types when you interact with them.
There is also a Function object, an a number of equivalent Wrappers for the other primitives in JavaScript, that means that you can even call methods on functions instances, like:
myFunction(someArg).call(this)
That being said, not every object is in fact a function.
As others have said, functions are objects that can be passed around by reference like other javascript objects. Not all objects are functions, only those that are declared as such.
You will often see methods declared like so:
var myFunc = function(foo, bar) {
...
};
This is to reinforce the fact that the method is a function object and as such it is a property of the object where it is defined, just like any other variable you might define with var.
This is the foundation of the most important feature in javascript, closure.
Every function is an Object.
I'm not an javascript expert, but I cannot see how every Object is a function. (I can see how every object could be a function, but that's different)
Quoting from Working with Objects - MDN Docs
section Using Object Initializers last paragraph:
"In JavaScript 1.1 and earlier, you cannot use object initializers. You can create objects only using their constructor functions or using a function supplied by some other object for that purpose. See Using a Constructor Function."
meant that all objects WERE functions! Specifically, upon evaluation, instances or instantiations of functions.
Literally, ALL objects of that vintage were created syntactically with constructs like:
"newobj = new constructFunctor(arg1,arg2){this.prop1=arg1 /* etc */}(val1,val2)"
AND in the string that makes the object "newobj" there is the word "constructFunctor", the name of a function. The statement is intentionally quoted to impress the fact that it must be eval()'d to be executed. Prior to execution "newobj" is "equated to" a function because the statement MUST have one and "is" one by virtue of "constructFunctor"'s literal existence to define newobj's value upon execution. The quoting, and not, is very intentional in order to elucidate this abstraction. However, because JavaScript DOES have an eval function, this abstraction is in fact intentionally incorporated into the JavaScript language.
The legacy of this is still fundamental to JavaScript, though some syntactic short cuts have been added as "object initializers" using the shorthand notation like: "no={}". That the paragraph quoted above is still resident in the current documentation IS significant for the very reasons noted.
Furthermore, JavaScript also exemplifies the fundamental paradigms of Functional Programming. This defines everything as a function using the abstractions of Recursive Function Theory and the Lambda Calculus! For instance 0(), 1(), 2(), ... are the constant nonary functions better known as 0,1,2,3, ...
JavaScript is completely consistent with a Functional Programming Style approach rather than the common OOPS (pun intended Object Oriented Programming Style).
Just for supplementary to Aaron Digulla's answer.
In javascript not every object is a function. But Object,Array,String and many other built-in objects are functions that used with new operator to create object. I think this is what confused most people.
javascript everything is a hashtable. Ryan Dahl said this in one of his talks. thats what json is also; a hashtable definition. thats why u can access an object using array notation or object property notation. the value of the hashtable can be a function as well which is a hashtable. or rather an associative array
type Object in the console u get { [native code] } which is a hashtable
Object is an abstract data given to a class and that class is assigned to an object. Object can have properties and properties can hold values and functions.
Or simply for the sake of making it easy to understand you can say that anything that is not primitive data type (number,string, boolean, unll & undefined) can be classified as an object.
the selected answer by Aaron Digulla's is not 100% correct because it says,
Anything that is not a primitive type (undefined, null, number,
string, boolean) is an object.
but a string is an object. That is why you can do things like:
myString="Hello World";
x = myString.length;
newString = myString.toUpperCase();
link = myString.link("http://www.hello-world.com/");
And many other methods can be applied to the string object.
You could also initialize the string like:
myString = new String("Hello, World!");
But because a string is also a datatype it is much easier to initialize it by just applying a value.
Not necessarily an answer to the question ... just a clarification/correction of Aaron Digulla's answer.
The selected answer is wrong. In JavaScript everything is a function, except primitive types. Object itself is a function which is called function Object(). Use for example the following code:
<script>
alert(Object);
</script>

Categories

Resources