Array.prototype.slice === [].slice // output true
console.log(Array.prototype) // output []
Why the following condition is false (taking above statements in count)
Array.prototype === [] //output (false)
Array.prototype.slice === [].slice // output true
console.log(Array.prototype) // output []
Why the following condition is false (taking above statements in count)
Array.prototype === [] //output (false)
Array.prototype
is an array itself and console.log
for any empty array (in Chrome...) outputs []
.
The strict equality operator (===
) compares references between the two arrays and Array.prototype
does not have the same reference as your array literal.
This is because of memory location.
For example, let's say you have two objects, {A}
and {B}
. Yes, both belong to the Object.prototype
; however, that does not mean {A} === {B}
. They don't necessarily carry the same properties or exist in the same memory location.
Similarly, Array.prototype
creates a blank array []
, much like typing the array literal, []
, does. These two calls are distinct, however, in that Array.prototype
returns the be-all and end-all of all arrays, whereas []
just instantiates a new array in memory. They both "return" the same thing in the console, but are actually quite different. This is why Array.prototype === Array.prototype
returns true
, while [] === []
returns false
. The MDN article on "Inheritance and the prototype chain" does a good job at explaining how .prototype
works in JavaScript.
So why exactly does Array.prototype === []
return false, when Array.prototype === Array.prototype
returns true, considering Array.prototype
returns []
? Well, this would be the same as saying var arr1 = []
and var arr2 = []
were equal; they're not.
For example, when you have two arrays:
var arr1 = [1,2,3];
var arr2 = [2,3,4];
You don't check for equality with if (arr1 === arr2)
, as that would only tell you if they existed in the same memory location. Instead, you loop through and compare the elements. It's the same concept for Array.prototype === []
, except the arrays have no elements.
The reason Array.prototype.slice === [].slice
returns true
is because it's comparing two functions, which both happen to be .slice
, meaning they occupy and reference the same memory location. It only makes sense that they are equal because they are indeed the same thing.
console.log([].slice);
// returns:
/*
function slice() {
[native code]
}
*/
// console.log(Array.prototype.slice) returns the same thing.
Try Array.prototype.slice === [].splice
—it returns false. Two different functions in two different locations. What about Array.prototype.slice() === [].slice()
? It returns false? What? Why?
Because each side of the equality operator references two different memory locations. You called .slice
on two different arrays, so now you're comparing two different slices of two different arrays, hence the false
return.
Without getting into prototype inheritance stuff ...
Two objects can be different, but some of their properties can reference the same thing.
var same = {};
var a = {test: same};
var b = {test: same};
console.log(a.test === b.test); // true
console.log(a === b); // false
a.name = 'a';
console.log(b.name); // undefined, because b is a different object
a.same.name = 'arnold';
console.log(b.same.name); // arnold