好的,我只是这样做了,挠了挠头。我在 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实现方式。