1

Please look at the code below:

function Foo() {}

Foo.prototype.toString = function toString() {
  return "[object Foo]";
}

var a = new Array();
var f = new Foo();

alert(a.toString()); // alerts [object Array]
alert(f.toString()); // alerts [object Foo]

alert(Object.prototype.toString.call(a)); // alerts [object Array]
alert(Object.prototype.toString.call(f)); // alerts [object Object]
  1. Why f.toString() and Object.prototype.toString.call(f) have different results? And why a.toString() and Object.prototype.toString.call(a) have the same results?

  2. How do I implement Foo.prototype.toString to return [object Foo] on call Object.prototype.toString? How to get the same behavior as on native types (Array, Date, Boolean etc.)


Sorry for my bad English...

NoSkill
  • 718
  • 5
  • 15
  • Possible duplicate of [What is the .call() function doing in this Javascript statement?](http://stackoverflow.com/questions/3250379/what-is-the-call-function-doing-in-this-javascript-statement) – Ilmari Karonen Oct 25 '16 at 10:51

3 Answers3

0

Why f.toString() and Object.prototype.toString.call(f) have different results?

Because they are different functions. The first you wrote yourself, the second is provided by the JS engine.

How do I implement Foo.prototype.toString to return [object Foo] on call Object.prototype.toString?

You can't.

Object.prototype.toString does what Object.prototype.toString does when you call it.

The existence of another function won't change what Object.prototype.toString does.

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • 2
    Ok... I mean Object.prototype.toString can detect the type of instance and return: [object Array] [object Date] [object RegExp] e.t.c. Why it can't return [object Foo]? – NoSkill Nov 29 '16 at 08:16
0

When you override a prototype property, it does not updates it in prototype, but adds a property to current object.

When calling a function, compiler starts with object and then goes up the prototype chain. So when you override, your function has highest priority. But when you do Object.prototype.toString.call, you are explicitly calling prototype function

Sample

function Foo(){
  this.toString = function(){
    console.log('This is object\'s function');
  }
}

Foo.prototype.toString= function(){
  console.log('This is prototype')
}

var f = new Foo();
console.log(f)

Following is prototype chain:

enter image description here

Community
  • 1
  • 1
Rajesh
  • 24,354
  • 5
  • 48
  • 79
0

The reason why f.toString() and Object.prototype.toString.call(f) have different results is because we have implicitly overridden the toString method of Foo.prototype, had we not overridden the toString method we would have got the similar result for f.toString() and Object.prototype.toString.call(f).

The reason why a.toString() and Object.prototype.toString.call(a) have same results is because the context in both the cases is same i.e variable a which is an array. The first parameter to call sets the context of execution. In this (Object.prototype.toString.call(a)) case it is a.

There is no way to implement Foo.prototype.toString to return [object Foo] on call Object.prototype.toString because when you override a prototype property, it does not updates it in prototype, but adds a property to the current object.

Nehal Gala
  • 516
  • 4
  • 5