I am a self taught web developer and am still trying to come to grips with some JavaScript fundamentals. Below are some quotes extracted from Douglas Crockford's Good Parts.
"Functions in JavaScript are Objects"
"In JavaScript, arrays are objects, functions are objects, regular expressions are objects, and, of course, objects are objects"
"Every object is linked to a prototype object from which it can inherit properties" (namely constructor, toString, ...)
If Function is an Object then why
console.log(typeof Function); // function
is its type a function and not object
console.log(Object.constructor); // Function()
is it the constructor of its 'parent'
console.log(Function.constructor); // Function()
puzzled so the constructor is in-fact a function?
console.log(typeof Function.prototype); // Function
is the type of its prototype a function and not an object? i thought it inherited from Object
Answers to these questions will greatly assist my understanding on JavaScript.
If Function is an Object then why is its type a function and not object?
Because the typeof operator is defined like that, probably for usability:
Object (native and does not implement [[Call]]) returns "object"
Object (native or host and does implement [[Call]]) returns "function"
Object (host and does not implement [[Call]])
returns an Implementation-defined value that may not be "undefined", "boolean", "number", or "string".
[[Call]] is an internal property of an object that identifies the object as a function (callable). A non-native object is an object provided by the host (e.g. browser), such as a DOM object or an instance of ActiveXObject.
puzzled so the constructor is in-fact a function?
Why wouldn't it be? Constructors are functions. Instances can only be constructed using functions. Object.constructor is a function, but it's also an object. See the following:
console.log((function () { }) instanceof Object);
//-> true
Also, from the ECMAScript speficiation:
Every built-in function and every built-in constructor has the Function prototype object, which is the initial value of the expression Function.prototype (15.3.4), as the value of its [[Prototype]] internal property.
Unless otherwise specified every built-in prototype object has the Object prototype object, which is the initial value of the expression Object.prototype (15.2.4), as the value of its [[Prototype]] internal property, except the Object prototype object itself.
And also, to answer your final puzzlement:
The Function prototype object is itself a Function object (its [[Class]] is "Function") that, when invoked, accepts any arguments and returns undefined.
When we say, "a function is an object", we don't mean "is" as in "instead of", we mean it in the same sense as "a cat is an animal". If someone asked you what kind of pet you had, you wouldn't answer "an animal". typeof would be useless if it always responded object.
A function is an object, but that's not an interesting thing for typeof to return, since it's a static quality of the language itself, not something that needs to be reported at runtime.
The typeof operator would be quite useless if it always returned "object", wouldn't it? Everything is an object, but it can be other things too. For example, a string is an object, but it is also a string :) The operator returns the name of the most specific type so to speak, not the most generic one. That should explain why typeof Functionis "function".
As for the constructor property, the constructor is a function that is invoked by the operator new when an object is created. It is always a function, regardless of whether the object itself is Object, Functionor something else.
The console.log(typeof Function); shows that the object is of type Function and not object.
To give you an example:
function squareValue(var x) {
return x * x;
}
can be loosely translated as
var squareValue = new Function("x", "return x*x");
and thus, doing
var valueSquared = squareValue(x);
in any of these 2 examples, will produce the same results...
Hence why every function in Javascript is a Function object.
The .constructor, .prototype, .toString on javascript Object/Function are all functions in their respective objects hence why you have the output as "function".
This is based according to the ECMA-262 3rd Edition -December 1999
Hope this helps.
reference Is every JavaScript Object a function?
javascript:alert([ window.navigator.userAgent, Object, Function ].join("\n\n") )
displays
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.3) Gecko/20100423
Ubuntu/10.04 (lucid) Firefox/3.6.3
function Object() {
[native code]
}
function Function() {
[native code]
}
also
javascript:alert([ new Object, new Function ].join("\n\n") )
displays
[object Object]
function anonymous() { }
and
javascript:alert([ new new Function ].join("\n\n") )
displays
[object Object]
Related
Why in JavaScript do both Object instanceof Function and Function instanceof Object return true?
I tried it in Safari WebInspector.
It took a while for me to figure out but its really worth the time spent. First, let us see how instanceof works.
Quoting from MDN,
The instanceof operator tests whether an object has in its prototype chain the prototype property of a constructor.
[instanceof]
Now, let us see how instanceof is defined by ECMA 5.1 Specification,
The production RelationalExpression: RelationalExpression instanceof ShiftExpression is evaluated as follows:
Let lref be the result of evaluating RelationalExpression.
Let lval be GetValue(lref).
Let rref be the result of evaluating ShiftExpression.
Let rval be GetValue(rref).
If Type(rval) is not Object, throw a TypeError exception.
If rval does not have a [[HasInstance]] internal method, throw a TypeError exception.
Return the result of calling the [[HasInstance]] internal method of rval with argument lval.
First the left and right hand side expressions are evaluated (GetValue) and then right hand side result should be an Object with [[HasInstance]] internal method. Not all objects will have [[HasInstance]] internal method, but functions. For example, the following will fail
console.log(Object instanceof {});
# TypeError: Expecting a function in instanceof check, but got #<Object>
[[HasInstance]]
Now, let us see how [[HasInstance]] has been defined in the ECMA 5.1 specification,
Assume F is a Function object.
When the [[HasInstance]] internal method of F is called with value V, the following steps are taken:
If V is not an object, return false.
Let O be the result of calling the [[Get]] internal method of F with property name "prototype".
If Type(O) is not Object, throw a TypeError exception.
Repeat
Let V be the value of the [[Prototype]] internal property of V.
If V is null, return false.
If O and V refer to the same object, return true.
It is so simple. Take the prototype property of F and compare it with the [[Prototype]] internal property of O until it becomes null or prototype of F is the same as O.
[[prototype]] internal property
First let us see what is the [[prototype]] internal property,
All objects have an internal property called [[Prototype]]. The value of this property is either null or an object and is used for implementing inheritance. Whether or not a native object can have a host object as its [[Prototype]] depends on the implementation. Every [[Prototype]] chain must have finite length (that is, starting from any object, recursively accessing the [[Prototype]] internal property must eventually lead to a null value).
Note: We can get this internal property with the Object.getPrototypeOf function.
prototype property
[[HasInstance]] also talks about another property called prototype, which is specific to the Function objects.
The value of the prototype property is used to initialise the [[Prototype]] internal property of a newly created object before the Function object is invoked as a constructor for that newly created object.
This means that, when a function object is used as a constructor, a new object will be created and the new object will have its internal [[Prototype]] initialized with this prototype property. For example,
function Test() {}
Test.prototype.print = console.log;
console.log(Object.getPrototypeOf(new Test()) === Test.prototype);
# true
Actual problem
Now let us get back to the actual question. Lets take the first case
console.log(Object instanceof Function);
# true
It will fetch Function.prototype first and it will try and find if that object is in the prototype hierarchy of Object. Let us see how that turns out
console.log(Function.prototype);
# [Function: Empty]
console.log(Object.getPrototypeOf(Object));
# [Function: Empty]
console.log(Object.getPrototypeOf(Object) === Function.prototype);
# true
Since the Function.prototype matches the Object's internal property [[Prototype]], it returns true.
Now lets take the second case
console.log(Function instanceof Object);
# true
console.log(Object.prototype);
# {}
console.log(Object.getPrototypeOf(Function));
# [Function: Empty]
console.log(Object.getPrototypeOf(Function) === Object.prototype);
# false
console.log(Object.getPrototypeOf(Object.getPrototypeOf(Function)));
# {}
Object.getPrototypeOf(Object.getPrototypeOf(Function)) === Object.prototype
# true
Here, first we get the Object.prototype, which is {}. Now it is trying to find if the same object {} is there in the Function's prototype chain. Immediate parent of Function is and Empty function.
console.log(Object.getPrototypeOf(Function));
# [Function: Empty]
It is not the same as Object.prototype
console.log(Object.getPrototypeOf(Function) === Object.prototype);
# false
But the [[HasInstance]] algorithm doesn't stop there. It repeats and gets up one more level
console.log(Object.getPrototypeOf(Object.getPrototypeOf(Function)));
# {}
And this is the same as Object.prototype. That is why this returns true.
From MDN:
The instanceof operator tests whether an object has in its prototype chain the prototype property of a constructor.
Essentially, it is checking if Object (not an instance of Object, but the constructor itself) has as an instance of Function.constructor somewhere up its prototype chain.
And, indeed:
> Function.__proto__.__proto__ === Object.prototype
true
> Object.__proto__ === Function.prototype
true
This explains why Object instanceof Function as well as the reverse.
ALL objects have an internal property called [[Prototype]]. The value of this property is either null or an object and is used for implementing inheritance. If you try to look up a key on an object and it is not found, JavaScript will look for it in the prototype chain.
The Function constructor creates new Function objects (instances of Function constructor). The prototype property is specific to Function objects. The Function constructor is itself a Function object (instance of Function constructor).
When a Function object is used as a constructor, a new object will be created and the new object will have its [[Prototype]] initialized with the prototype property of the constructor.
function Dog () {}
var myCrazyDog = new Dog();
myCrazyDog.__proto__ === Dog.prototype // true
The language spec is that all objects are instances of Object constructor, and all functions are instances of Function constructor.
Object instanceof Function is true because Object is a function and thus is an instance of Function (Object is a Function object - an instance of the Function constructor). Object inherits from Function.prototype.
console.log(Object instanceof Function) // true
console.log(Object.__proto__ === Function.prototype) // true
Object instanceof Object is true because Object inherits from Function.prototype. Since Function.prototype is an object, it inherits from Object.prototype.
Function instance of Object is true because Function inherits from Function.prototype. Since Function.prototype is an object, it inherits from Object.prototype.
The prototype chain looks like this:
Object ---> Function.prototype ---> Object.prototype ---> null
Function ---> Function.prototype ---> Object.prototype ---> null
console.log(Object instanceof Object) // true
console.log(Object.__proto__ === Function.prototype) // true
console.log(Object.__proto__.__proto__ === Object.prototype) // true
console.log(Function instanceof Object) // true
console.log(Function.__proto__ === Function.prototype) // true
console.log(Function.__proto__.__proto__ === Object.prototype) // true
Function instanceof Function is true. Function is an instance of itself (naturally, since it’s a function, and thus an instance of Function). The prototype chain looks like this:
Function ---> Function.prototype ---> Object.prototype ---> null
console.log(Function instanceof Function) // true
console.log(Function.__proto__ === Function.prototype) // true
console.log(Function.__proto__.__proto__ === Object.prototype) // true
Thus keep in mind that the Function() and Object() constructors are functions. Since they are functions they are instances of the Function() constructor and inheriting from Function.prototype.
Since Function.prototype is an object, Function.prototype is an instance of Object, thus inheriting from Object.prototype.
console.log(Object instance of Function) // true
console.log(Function instance of Function) // true
console.log(Function.prototype instanceof Object); // true
The source of the confusion in your question lies in the inherent dual nature of functions* in JavaScript (ECMAScript).
Functions in js are both regulars functions and objects at the same time. Think of them as algorithmic Dr. Jekyll and Mr. Hyde. They look like objects on the outside but inside they're just your good old js functions with all their quirks, or maybe it's the other way around!
JavaScript is really a tricky business :)
So back to your question, borrowing the syntax appearing on MDN:
object instanceof constructor
Applying it on the first statement in your code:
Object instanceof Function
Here you have Object, a constructor function that's used as an object initializer but since functions lead a double life in js, it has object-specific props and methods attached to it rendering it effectively an object too.
So, the first condition in the statement has been met. We remain to investigate the other condition or operand.
Function as you might have noticed is also function constructor but its other object side is of no interest to us now during the execution of this particular statement.
So, the syntactic conditions are both met namely "object" and "constructor". We can now then proceed to investigate their hereditary relation and if there's a connection between them.
Since Object is a working function itself, it makes a lot of sense to assume that it has its internal prototype prop pointing to the Function.prototype object reference since in js ALL functions inherit their props and methods through that same location Function.prototype.
true is definitely the ONLY expected outcome of this comparison performed by the instanceof operator.
For the other case:
Function instanceof Object
Since we established already that functions in js have also an object side to them. It makes sense that they got their fancy object-specific toys from the Object.prototype, and therefore they constitute instances of the Object constructor.
Hope I didn't add to the confusion with my explanation and allegories. :)
*: Not only functions that lead a double life in js. Almost all data types in js have an object dark side to them that facilitate completing operations and manipulations without any hassle.
The most badass property is actually that Function is an instance of itself. Function instanceof Function returns true.
It is nicely explained in Kannan's The Surprisingly Elegant Javascript Type Model, at http://web.archive.org/web/20140205182624/http://vijayan.ca/blog/2012/02/21/javascript-type-model
Quote at the end of the explanation:
Yes, this means that Function is an instance of itself (naturally, since it’s a function, and thus an instance of Function). This is something we’ve all been dealing with, knowingly or not, for a long time now – all constructor functions are regular functions and thus instances of Function, and Function itself is just the constructor function for constructing other functions, so it too is an instance of Function.
Very Simple Explanation, Different from all answers
Both Object and Function are constructors(type of both with return "Function objects") and both are created from Function Constructor.
The __proto__ property of both these point to 'Function.prototype' object.
QUICK EXPLANATION: __proto__ property of an object(say p1 which is Person type) points to the Constructor's protoype(say Person.prototype)
Again the __proto__ in the prototype chain points to the object "Object.prototype".
BEFORE READING FURTHER PRINT DETAILS ON CHROME CONSOLE console.dir(Object), console.dir(Function)
KEEP IN MIND, function constructors and also objects so you will see both .prototype and __proto__ properties. In all the instance objects(say p1) you will only find the __proto__ property. The __proto__ is accessor for hidden property [[Prototye]] and best way to get is Object.getPrototypeOf(p1) as __proto__ is depricated.
(p1 instanceof Person) here operator checks if the Constructor Person's prototype is in the prototypal chain of the object p1. take a note that first value is instance object(p1) and second value is a constructor (Person).
Lets analyze => Function instanceof Object.
Function object's __proto__.__proto__ points to Object.prototype , So its true
Lets analyze => Object instanceof Function.
Object object's __proto__ points to Function.prototype, So its true
Hope this helps.
Object is a built-in constructor function for objects. It is therefore a function (an instance of Function). Functions are objects in JavaScript, it is therefore an object too (an instance of Object).
Mozilla.org states that
The isPrototypeOf() method checks if an object exists in another object's prototype chain.
When I create a primitive variable, say
var a = 0;
And check for its [[Prototype]] (not a.prototype),
console.log(a.__proto__); //on chrome
It prints Number {0, isDivisibleBy2: ƒ, constructor: ƒ, toExponential: ƒ, toFixed: ƒ, …}. Apparently, this value seems to be what's inside the Number.prototype.
So, I expect Number.prototype.isPrototypeOf(a); to return true, since Number.prototype does indeed exist within the prototype chain of a (the __proto __ chain).
But instead, theboutput for Number.prototype.isPrototypeOf(a); is false.
var a = 0;
console.log(a.__proto__);
console.log(Number.prototype);
console.log(Number.prototype === a.__proto__);
console.log(Number.prototype.isPrototypeOf(a));
I think I might be misunderstanding something... I believe that value.__proto__ is the right way to access the prototype chain (understang from this mozilla link). Is it just that isPrototypeOf() does not work on primitive?
Can someone help me clear up and understand this weird phenomenon?
JavaScript is actually creating a new Number object from the primitive when you access a property on it or call a method, after which the new object is promptly thrown away. That is why you can access the __proto__ property. The primitive, however, is not a Number object.
As you can see in the spec here, the first rule of isProtoTypeOf is "If Type(V) is not Object, return false" (Where V is the value passed to the method).
I came across the following table which states the internal [[Class]] property of an object and its corresponding value that the typeof operator returns.
Value Class Type
-------------------------------------
"foo" String string
new String("foo") String object
1.2 Number number
new Number(1.2) Number object
true Boolean boolean
new Boolean(true) Boolean object
new Date() Date object
new Error() Error object
[1,2,3] Array object
new Array(1, 2, 3) Array object
new Function("") Function function
/abc/g RegExp object (function in Nitro/V8)
new RegExp("meow") RegExp object (function in Nitro/V8)
{} Object object
new Object() Object object
One thing to note here is the typeof correctly returns the primitive data types associated in Javascript.
However, it returns an object type for an array which inherits from the Array.prototype, but returns a function type for a function that is inheriting from the Function.prototype.
Given everything is an object in Javascript (including arrays, functions & primitive data type objects), I find this behaviour of the typeof operator very inconsistent.
Can someone throw some light on how the typeof operator works in reality?
This is slightly odd, idiosyncratic Javascript behaviour. It's inherited from the earliest days of Javascript and probably would not be written in such a way today.
Nonetheless, we are where we are with Javascript, so we have to deal with it!
The thing is that values in Javascript are either objects or they are primitives. This is a design decision. They cannot be anything else. The types of primitives are:
strings
numbers
booleans
symbols (from ES2015)
the special value undefined
the special value null (for which typeof also returns object)
Anything and everything else is an object. This is by design. Arrays are objects, so typeof returns object, as does every other object that is not callable (i.e. a function). See the spec for typeof.
The better question is to ask why you want to test if something is an array. You probably don't need to, especially as array-like objects such as NodeLists are not arrays but are like them in many ways.
The best solution in most cases is to call Array.from on the value supplied: then you know that it is an array.
Use typeof operator in JavaScript
'Typeof' is an operator which is used to return a string description of the type of a variable.
Example
console.log(typeof 42);
output: "number"
console.log(typeof true);
output: "boolean"
The MDN said :
Six data types that are primitives:
Boolean
Null
Undefined
Number
String
Symbol (new in ECMAScript 6)
and Object
But I confused, the function data type and object data type.
Let's see :
var func = function() {
console.log ('Hello World ! ')
};
var obj = {
property : something
}
console.log(typeof(func)); // ===> function
console.log(typeof(obj)); // ===> object
Is it different function data type and object data type? Why typeof(func) is function? not a object? The document said there are 7 data type (6 primitive, 1 object). function is not include anywhere.
Until now, over 1 year, I think function's data type is object, I heard the function is first class object in JavaScript, so I don't have doubt about function is object but today I think more time, and wondered.
Is it different?
You can logically think of Function as a subclass of Object. It has all the methods of Object plus some more that are specific to a function (such as .bind(), .call(), .apply(), etc...).
Why Javascript decided to make Function report it's own unique type, but not Array (which is a similar derivation from Object) is anyone's guess and probably only known to the original designers of the language. It is extremely useful that Function does report its own type so you can easily check if a property is callable as a function and perhaps that is the main reason why it was done this way.
Here's a demonstration of how a Function object has the methods from an Object:
function f() {}
f.someProperty = "foo";
log(f.hasOwnProperty("someProperty"));
log(f instanceof Object);
log(f instanceof Function);
function log(x) {
var div = document.createElement("div");
div.innerHTML = x;
document.body.appendChild(div);
}
typeof returns the type of what ever is passed to it. A function is an object ((function () {}) instanceof Object === true), but the typeof function is defined to return "function" when an Object implements [[Call]] in ECMA-262 is supplied to it.
Functions are objects, but typeof treats them as a special case.
I'm actively learning javascript, and I came across the following statement:
Object.prototype.toString.call([]);
And I don't know what it means or what it does.
I have a vague understanding of .call, in that it allows you to call a method in the context of a different object (I think), but I am having a hard time understanding what role the .call() function is playing in the above statement. So I was wondering if anyone could explain what .call() is doing here?
Thanks!!
The call method sets the this value of the invoked function to the object passed as first argument, in your example, you are executing the Object.prototype.toString method on an Array object.
Array objects, have their own toString method (Array.prototype.toString) that shadows the one from Object.prototype, if you call [].toString(); the method on the Array.prototype will be invoked.
For example:
function test() {
alert(this);
}
test.call("Hello"); // alerts "Hello"
Another example:
var alice = {
firstName: 'Alice',
lastName: 'Foo',
getName: function () {
return this.firstName + ' ' + this.lastName;
}
};
var bob = {
firstName: 'Bob',
lastName: 'Bar',
};
alice.getName.call(bob); // "Bob Bar"
In the above example, we use the Alice's getName method on the Bob's object, the this value points to bob, so the method works just as if it were defined on the second object.
Now let's talk about the Object.prototype.toString method. All native objects in JavaScript contain an internal property called [[Class]] this property contains a string value that represents the specification defined classification of an object, the possible values for native objects are:
"Object"
"Array"
"Function"
"Date"
"RegExp"
"String"
"Number"
"Boolean"
"Error" for error objects such as instances of ReferenceError, TypeError, SyntaxError, Error, etc
"Math" for the global Math object
"JSON" for the global JSON object defined on the ECMAScript 5th Ed. spec.
"Arguments" for the arguments object (also introduced on the ES5 spec.)
"null" (introduced just a couple of days ago in the ES5 errata)
"undefined"
As I've said before that property is internal, there is no way to change it, the specification doesn't provide any operator or built-in function to do it, and the only way you can access its value is through the Object.prototype.toString method.
This method returns a string formed by:
"[object " + this.[[Class]] + "]"
Only for expository purposes because [[Class]] cannot be accessed directly.
For example:
Object.prototype.toString.call([]); // "[object Array]"
Object.prototype.toString.call(/foo/); // "[object RegExp]"
Object.prototype.toString.call({}); // "[object Object]"
Object.prototype.toString.call(new Date); // "[object Date]"
// etc...
This is really useful to detect the kind of an object in a safe way, for detecting array objects, it's the most widely used technique:
function isArray(obj) {
return Object.prototype.toString.call(obj) == '[object Array]';
}
It might be tempting to use the instanceof operator, but that way will lead to problems if you work on cross-frame environments, because an array object created on one frame, will not be instanceof the Array constructor of another.
The above method will work without any problems, because the object will contain the value of its [[Class]] internal property intact.
See also:
instanceof considered harmful (or how to write a robust isArray)
Object.prototype.toString
Object Internal Properties and Methods
Because toString is mostly not invoked with a parameter, not toString('foo'), but bar.toString(). Which is where call comes in handy.
Different toStrings
I say "mostly" because there are different toStrings:
Object.prototype.toString returns a string representing object
Array.prototype.toString returns a string representing the specified array and its elements
Number.prototype.toString returns a string representing the specified Number object
String.prototype.toString returns a string representing the specified String object
Function.prototype.toString returns a string representing the source code of the function
Instance of Uses Separately
(new Object()).toString(); // "[object Object]"
["foo", "bar"].toString(); // "foo,bar"
(6).toString(2); // "110"
("meow").toString(); // "meow"
(function(){return 'x';}).toString() // "function (){return 'x';}"
Though all object prototypically inherit from Object, the latter ones don't inherit toString from Object's toString, which means that they're all different things and have different uses. To tell the type of an object, Object.prototype.toString is the useful one, since it returns a type:
Every object has a toString() method that is automatically called when the object is to be represented as a text value or when an object is referred to in a manner in which a string is expected. By default, the toString() method is inherited by every object descended from Object. If this method is not overridden in a custom object, toString() returns "[object type]", where type is the object type.
Call
Note that among them the only one that takes parameter is Number.prototype.toString, and it's for specifying base of the outcome number. Therefore, in order to invoke Object.prototype.toString for arrays, numbers and other object that has their own toString method, you need call to specify this:
Object.prototype.toString.call(Math); // [object Math]
Object.prototype.toString.call(new Date); // [object Date]
Object.prototype.toString.call(new String); // [object String]
Object.prototype.toString.call(Math); // [object Math]
// Since JavaScript 1.8.5
Object.prototype.toString.call(undefined); // [object Undefined]
Object.prototype.toString.call(null); // [object Null]