2
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)   
Kishorevarma
  • 936
  • 6
  • 23
  • 5
    The methods are the same because they point to the same function, the objects are different, not the same object, `[] !== []` – elclanrs Jul 29 '14 at 19:15
  • I guess you want to learn about the prototype chain: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Inheritance_and_the_prototype_chain – Felix Kling Jul 29 '14 at 19:29
  • If you would like to know more about prototype in JavaScript and constructor functions then maybe the following answer can be of help: http://stackoverflow.com/a/16063711/1641941 It doesn't cover Array.prototype being an instance of Array (I didn't know that before) but explains what prototype is and how constructor functions can be used. – HMR Jul 30 '14 at 04:16

3 Answers3

2

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.

dee-see
  • 23,668
  • 5
  • 58
  • 91
  • "`Array.prototype` is an array itself" `Array.prototype instanceof Array` -> false – guest Jul 29 '14 at 19:21
  • 1
    @guest `instanceof` compares prototypes and I guess using it on the prototype itself produces some weird results, but calling `Object.prototype.toString.call(Array.prototype)` outputs `"[object Array]"`. Also `Array.isArray(Array.prototype)` outputs `true`. – dee-see Jul 29 '14 at 19:22
  • 1
    @guest: *"The Array prototype object is itself an array; its [[Class]] is "Array", and it has a length property (whose initial value is +0) and the special [[DefineOwnProperty]] internal method described in 15.4.5.1."* http://es5.github.io/#x15.4.4 – Felix Kling Jul 29 '14 at 19:27
  • Thanks for the link, Felix. Turns out to be an *array* (lowercase a, I guess) an object needs to have its [[Class]] internal property set to "Array" (http://es5.github.io/#x15.4.3.2). This is different from being an *Array object* in the OO model. – guest Jul 29 '14 at 19:37
  • @guest From the MDN: `The instanceof operator tests whether an object has in its prototype chain the prototype property of a constructor.` Array.prototype doesn't have Array.prototype in its prototype chain. Similarly, `fooPrototype instnaceof Foo` is `false` in this example: `Foo=function(){};fooPrototype={};Foo.prototype=fooPrototype;fooPrototype instanceof Foo;` – Max Heiber Jul 29 '14 at 19:40
  • @guest: I guess JavaScript is just... different :) – Felix Kling Jul 29 '14 at 20:30
2

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.

royhowie
  • 11,075
  • 14
  • 50
  • 67
  • Please edit. You are correct that `[]===[]` is false but the first sentence of your third paragraph is incorrect if I understand it correctly. "Array.prototype" does not "create a blank array with the same effect as typing `[]`. There is one array prototype object. So `Array.prototype===Array.prototype` evaluates to `true`. – Max Heiber Jul 29 '14 at 19:32
  • @mheiber This is true. I'll fix it. – royhowie Jul 29 '14 at 19:35
1

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
guest
  • 6,450
  • 30
  • 44