Reputation: 99
Let's say we do this:
function Dog(name, breed) {
this.name = name;
this.breed = breed;
}
var date = new Date();
var dog = new Dog("YOU'RE", "READING");
var zehbi = Object.prototype.toString.call(date);
var zehbi2 = Object.prototype.toString.call(dog);
console.log(zehbi);
console.log(zehbi2);
Why does zehbi
return the name of its constructor function "Date" but zehbi2
doesn't return the name of it's constructor function "Dog" but returns "Object" instead?
Upvotes: 1
Views: 221
Reputation: 40872
Because it is defined that way in the specification:
20.1.3.6 Object.prototype.toString ( )
When thetoString
toString method is called, the following steps are taken:
- If the
this
value isundefined
, return "[object Undefined]".- If the
this
value isnull
, return "[object Null]".- Let
O
be ! ToObject(this value).- Let
isArray
be ? IsArray(O).- If
isArray
istrue
, letbuiltinTag
be "Array".- Else if
O
has a[[ParameterMap]]
internal slot, letbuiltinTag
be "Arguments".- Else if
O
has a[[Call]]
internal method, letbuiltinTag
be "Function".- Else if
O
has an[[ErrorData]]
internal slot, letbuiltinTag
be "Error"`.- Else if
O
has a[[BooleanData]]
internal slot, letbuiltinTag
be "Boolean".- Else if
O
has a[[NumberData]]
internal slot, letbuiltinTag
be "Number".- Else if
O
has a[[StringData]]
internal slot, letbuiltinTag
be "String".- Else if
O
has a[[DateValue]]
internal slot, letbuiltinTag
be "Date".- Else if
O
has a[[RegExpMatcher]]
internal slot, letbuiltinTag
be "RegExp".- Else, let
builtinTag
be "Object"- Let
tag
be ?Get(O, @@toStringTag)
.- If
Type(tag)
is notString
, settag
tobuiltinTag
.- Return the string-concatenation of "[object ", tag, and "]".
And for Date
the point 12. is true because it has an [[DateValue]]
internal slot, your Dog
does not match any of the 5. to 13. so 14. is used. After that 15. checks for the existence of @@toStringTag
which does not return a string for Dog
or Date
, so the tag
becomes the builtinTag
given by one of the 5. to 14..
Upvotes: 1
Reputation: 29088
The result of Object.prototype.toString()
is determined by two things:
"[object Date]"
.@@toStringTag
.For the normal objects, prior to ES6 the default toString()
would only produce "[object Object]"
while post ES6 the result is the string "[object @@toStringTag]"
by using the value of the symbol. By default the value for the symbol is "Object"
.
You can override it for a custom class:
function Dog(name, breed) {
this.name = name;
this.breed = breed;
}
Dog.prototype[Symbol.toStringTag] = "Dog";
var dog = new Dog("YOU'RE", "READING");
var zehbi2 = Object.prototype.toString.call(dog);
console.log(zehbi2);
Or any object:
var obj = {
[Symbol.toStringTag]: "Custom"
}
console.log(Object.prototype.toString.call(obj));
console.log(obj.toString());
You can even override it for built-in objects:
var obj = new Date()
obj[Symbol.toStringTag] = "Custom";
console.log(Object.prototype.toString.call(obj));
Upvotes: 1