好的,我只是这样做了,挠了挠头。我在 Chrome 控制台上尝试了以下操作:
var a = [];
toString.call(a); //[object Array]
a.toString(); //""
toString(a); //[object Object] I know it's blunder but still!
toString 和 .toString 有什么区别我绝对知道它们来自不同的范围(对象),但是应该在什么时候使用哪个呢?为什么这么乱?
好的,我只是这样做了,挠了挠头。我在 Chrome 控制台上尝试了以下操作:
var a = [];
toString.call(a); //[object Array]
a.toString(); //""
toString(a); //[object Object] I know it's blunder but still!
toString 和 .toString 有什么区别我绝对知道它们来自不同的范围(对象),但是应该在什么时候使用哪个呢?为什么这么乱?
首先我们要明确toString
指的是Object.prototype.toString
:
> toString === Object.prototype.toString
true
规范的第 15.2.4.2 节Object.prototype.toString
解释了工作原理:
- 如果
this
值为undefined
,则返回"[object Undefined]"
。- 如果
this
值为null
,则返回"[object Null]"
。- 让
O
是调用ToObject
将this
值作为参数传递的结果。- 设
class
为 的[[Class]]
内部属性的值O
。"[object "
返回作为连接三个 String 、class
和的结果的 String 值"]"
。
toString.call(a)
与上述算法相同Object.prototype.toString.call(a)
并根据上述算法工作:this
引用数组a
(因为您使用.call
了 ),内部[[Class]]
属性具有值Array
,因此输出为[object Array]
.
a.toString()
: 数组会覆盖第 15.4.4.2 节toString
中定义的属性。简而言之,所有数组元素都被连接起来,并且由于数组为空,因此您会得到一个空字符串作为结果。
toString(a)
是一样的Object.prototype.toString()
。该论点被简单地忽略。因此this
指的是Object.prototype
,它是一个对象,根据上面提到的算法,输出是[object Object]
。对于 的任何值,输出都是相同的a
。
应该在什么时间使用哪一个?
这取决于你想做什么。就个人而言,我发现没有一个内置toString
函数特别有用,除了一些快速和肮脏的调试。
toString.call(a)
应该== a.toString()
好吧,Object.prototype.toString
这Array.prototype.toString
只是两种不同的方法,因此您会得到不同的结果。
您可能会争辩说, 如果存在就Object.prototype.toString
应该调用覆盖toString
,但这不是toString
实现方式。