[英]Why does Object.prototype.toString return constructor function name on some objects?
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?为什么zehbi
返回其构造函数的名称 function "Date" 而zehbi2
不返回其构造函数的名称 function "Dog" 而是返回 "Object"?
Because it is defined that way in the specification:因为它在规范中是这样定义的:
20.1.3.6 Object.prototype.toString ( ) 20.1.3.6 Object.prototype.toString ( )
When thetoString
toString method is called, the following steps are taken:当调用toString
toString 方法时,执行以下步骤:
- If the
this
value isundefined
, return "[object Undefined]".如果this
值为undefined
,则返回“[object Undefined]”。- If the
this
value isnull
, return "[object Null]".如果this
值为null
,则返回“[object Null]”。- Let
O
be.让O
成为。 ToObject(this value). ToObject(这个值)。- Let
isArray
be?让isArray
成为? IsArray(O).是数组(O)。- If
isArray
istrue
, letbuiltinTag
be "Array".如果isArray
为true
,则让builtinTag
为“Array”。- Else if
O
has a[[ParameterMap]]
internal slot, letbuiltinTag
be "Arguments".否则,如果O
有一个[[ParameterMap]]
内部槽,则让builtinTag
为“Arguments”。- Else if
O
has a[[Call]]
internal method, letbuiltinTag
be "Function".否则如果O
有一个[[Call]]
内部方法,让builtinTag
为“Function”。- Else if
O
has an[[ErrorData]]
internal slot, letbuiltinTag
be "Error"`.否则,如果O
有一个[[ErrorData]]
内部槽,则让builtinTag
为“Error”`。- Else if
O
has a[[BooleanData]]
internal slot, letbuiltinTag
be "Boolean".否则如果O
有一个[[BooleanData]]
内部槽,让builtinTag
为“Boolean”。- Else if
O
has a[[NumberData]]
internal slot, letbuiltinTag
be "Number".否则如果O
有一个[[NumberData]]
内部槽,让builtinTag
为“Number”。- Else if
O
has a[[StringData]]
internal slot, letbuiltinTag
be "String".否则如果O
有一个[[StringData]]
内部槽,让builtinTag
为“String”。- Else if
O
has a[[DateValue]]
internal slot, letbuiltinTag
be "Date".否则如果O
有一个[[DateValue]]
内部槽,让builtinTag
为“Date”。- Else if
O
has a[[RegExpMatcher]]
internal slot, letbuiltinTag
be "RegExp".否则如果O
有一个[[RegExpMatcher]]
内部槽,让builtinTag
为“RegExp”。- Else, let
builtinTag
be "Object"否则,让builtinTag
为“对象”- Let
tag
be?让tag
成为?Get(O, @@toStringTag)
.Get(O, @@toStringTag)
。- If
Type(tag)
is notString
, settag
tobuiltinTag
.如果Type(tag)
不是String
,则将tag
设置为builtinTag
。- 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.对于Date
,点12.是真的,因为它有一个[[DateValue]]
内部槽,你的Dog
与5.到13.中的任何一个都不匹配,所以使用14. 。 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. .在那之后15.检查@@toStringTag
是否存在,它不返回Dog
或Date
的字符串,所以tag
变成builtinTag
由5.到14.之一给出。
The result of Object.prototype.toString()
is determined by two things: Object.prototype.toString()
的结果由两件事决定:
"[object Date]"
.该规范确定了哪些内置函数将被标识为并且 Date 将显示为"[object Date]"
。@@toStringTag
.从 ES6 开始 - 众所周知的符号@@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.对于普通对象,在 ES6 之前,默认的toString()
只会产生"[object Object]"
,而在 ES6 之后,结果是使用符号值的字符串"[object @@toStringTag]"
。 By default the value for the symbol is "Object"
.默认情况下,符号的值为"Object"
。
You can override it for a custom class:您可以为自定义 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:或任何 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));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.