如果您致电Object.prototype.toString.call(anything)
,结果始终为[object Something]
,其中Something
可能是其中之一。我的问题是为什么“对象”在那里?总是把它放在那里似乎是多余的。它没有告诉你关于传入的论点的任何信息。
Object.prototype.toString.call(null);
=> [object Null]
Object.prototype.toString.call(undefined);
=> [object Undefined]
由于null
和undefined
不是对象(并且CheckObjectCoercible
失败),因此“对象”部分确实显得毫无意义。
我不得不认为最初有一些原因是“对象”部分放在那里,即使原因已经丢失了,现在它已经因历史原因而被保留了。
任何人都可以帮忙解释一下吗?
要清楚,我已经知道Object.prototype.toString
如何用于获取对象的[[Class]]
(类型)。我的问题涉及返回字符串格式的原因 - 特别是开头的“对象”部分。我想知道这一部分是否有原因,或者这部分是否有可能的未来原因。也许在未来它可能会返回“对象”以外的东西?我能指望它总是返回“对象”吗?如果是这样,为什么它甚至返回呢?谁想要一个函数总是返回相同的东西,无论输入是什么?
答案 0 :(得分:3)
Annex F of the ES5.1 specification说Object.prototype.toString
:
15.2.4.2:版本5处理undefined和null,因为此值导致现有代码失败。修改了规范以保持与此类代码的兼容性。新的步骤1和2添加到算法中。
这是在ES5.1规范中进行的更正。在ES5之前,将null或undefined传递给toString总是会导致传递全局对象。 ES5中与严格模式相关的更改会导致null和undefined无需修改即可传递。如ES5中所指定,将null或undefined传递给Object.prototype.toString
会导致TypeError异常。这个例外打破了一些现有的代码,因此我们必须修改规范,以免在这种情况下抛出。
那么toString
应该返回null和undefined?事实证明,许多现有代码还希望Object.prototype.toString
始终返回"[object *]"
形式的字符串。因此,我们决定使null和undefined生成"[object Null]"
和"[object Undefined]"
。
这似乎已经奏效并且通常允许现有的基于ES3的代码在ES5 / 5.1中存在严格模式相关更改的情况下继续工作。
答案 1 :(得分:2)
好的,想到这样:
undefined
和null
在解释器中实现为单例对象。例如,undefined
实际上是Rhino中的Undefined.instance
(用Java实现)。toString
方法公开JavaScript值的类名。但是,由于该值不是类本身而是类的实例,toString
将返回[object ClassName]
形式的字符串。[object *]
表单是多余的。然而有人希望它像那样,所以我们坚持下去。现在它就在那里,如果突然发生变化,它会引起很多问题。依赖它的旧代码可能会破坏。编辑:重要的是要注意JavaScript何时结束并且解释器开始。例如,当您在JavaScript中调用函数时,解释器会创建一个新的执行上下文,该上下文是编写JavaScript解释器的语言中的对象(而不是JavaScript本身)。
类似地,JavaScript值的[[Class]]
是编写JavaScript解释器的语言中的类,用于创建该类的实例。例如,在Rhino函数中是类org.mozilla.javascript.BaseFunction
的实例。此类有一个名为getClassName
的方法returns Function
([[Class]]
个实例的BaseFunction
。
类似地,有一个名为org.mozilla.javascript.Undefined
的类,它有一个名为instance
的静态属性,它是Undefined
的{{3}}。
答案 2 :(得分:1)
以下是ES5的说法:
15.2.4.2 Object.prototype.toString ( )
调用toString方法时,将执行以下步骤:
- 如果未定义此值,请返回“[object Undefined]”。
- 如果此值为null,则返回“[object Null]”。
- 设O是调用ToObject传递此值作为参数的结果。
- 让class为O的[[Class]]内部属性的值。
- 返回String值,该值是连接三个字符串“[object”,class和“]”的结果。
醇>
因此toString
首先处理undefined
和null
,然后将参数转换为对象,然后返回该对象的内部[[Class]]
属性。请注意,toString
旨在被对象所包含,因此它的行为就像它一样公平。
在ECMAScript中,一切都是对象。基元只是避免以下事情的便利:
// Create number objects with the same value
var a = new Number(7);
var b = new Number(7);
a == b; // false
a.valueOf() == b.valueOf(); // true
JavaScript的主要目标是简单。宽松的打字使生活更轻松,但这也意味着有一些缺点需要学习。