简体   繁体   English

为什么 Object.prototype.toString 在某些对象上返回构造函数 function 名称?

[英]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 the toString toString method is called, the following steps are taken:当调用toString toString 方法时,执行以下步骤:

  1. If the this value is undefined , return "[object Undefined]".如果this值为undefined ,则返回“[object Undefined]”。
  2. If the this value is null , return "[object Null]".如果this值为null ,则返回“[object Null]”。
  3. Let O be.O成为。 ToObject(this value). ToObject(这个值)。
  4. Let isArray be?isArray成为? IsArray(O).是数组(O)。
  5. If isArray is true , let builtinTag be "Array".如果isArraytrue ,则让builtinTag为“Array”。
  6. Else if O has a [[ParameterMap]] internal slot, let builtinTag be "Arguments".否则,如果O有一个[[ParameterMap]]内部槽,则让builtinTag为“Arguments”。
  7. Else if O has a [[Call]] internal method, let builtinTag be "Function".否则如果O有一个[[Call]]内部方法,让builtinTag为“Function”。
  8. Else if O has an [[ErrorData]] internal slot, let builtinTag be "Error"`.否则,如果O有一个[[ErrorData]]内部槽,则让builtinTag为“Error”`。
  9. Else if O has a [[BooleanData]] internal slot, let builtinTag be "Boolean".否则如果O有一个[[BooleanData]]内部槽,让builtinTag为“Boolean”。
  10. Else if O has a [[NumberData]] internal slot, let builtinTag be "Number".否则如果O有一个[[NumberData]]内部槽,让builtinTag为“Number”。
  11. Else if O has a [[StringData]] internal slot, let builtinTag be "String".否则如果O有一个[[StringData]]内部槽,让builtinTag为“String”。
  12. Else if O has a [[DateValue]] internal slot, let builtinTag be "Date".否则如果O有一个[[DateValue]]内部槽,让builtinTag为“Date”。
  13. Else if O has a [[RegExpMatcher]] internal slot, let builtinTag be "RegExp".否则如果O有一个[[RegExpMatcher]]内部槽,让builtinTag为“RegExp”。
  14. Else, let builtinTag be "Object"否则,让builtinTag为“对象”
  15. Let tag be?tag成为? Get(O, @@toStringTag) . Get(O, @@toStringTag)
  16. If Type(tag) is not String , set tag to builtinTag .如果Type(tag)不是String ,则将tag设置为builtinTag
  17. 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]]内部槽,你的Dog5.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是否存在,它不返回DogDate的字符串,所以tag变成builtinTag5.14.之一给出。

The result of Object.prototype.toString() is determined by two things: Object.prototype.toString()的结果由两件事决定:

  • The type of built-in object it is executed against.它执行的内置类型 object。 The specification determine what built-ins will be identified as and a Date will say "[object Date]" .该规范确定了哪些内置函数将被标识为并且 Date 将显示为"[object Date]"
  • As of ES6 - the well-known symbol @@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.

相关问题 为什么`Object.prototype.toString`总是返回`[object *]`? - Why does `Object.prototype.toString` always return `[object *]`? 为什么Object.prototype.toString.call()提供的输出与Object.prototype.toString()不同? - Why does Object.prototype.toString.call() give different output than Object.prototype.toString()? Object.prototype.toString是函数还是属性? - Is Object.prototype.toString a function or a property? 为什么不使用Object.prototype.toString()来检查redux中的普通对象? - Why not use Object.prototype.toString() to check plain object in redux? 将Object.prototype.toString函数与undefined和null一起使用 - using Object.prototype.toString function with undefined and null 如何更改 Object.prototype.toString? - How to change Object.prototype.toString? Object.prototype.toString()的用途是什么? - What is the purpose of Object.prototype.toString()? Object.toString和Object.prototype.toString之间有所不同 - different between Object.toString and Object.prototype.toString JavaScript:Object.prototype.toString(new Number(5))似乎返回了错误的类型 - JavaScript: Object.prototype.toString(new Number(5)) seems to return a wrong type Object.prototype.toString和toString有什么不同? - What different between Object.prototype.toString and toString?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM