3

如果你调用Object.prototype.toString.call(anything)result is always [object Something], whereSomething可能是几件事之一。我的问题是为什么“对象”部分在那里?总是把它放在那里似乎是多余的。它不会告诉您有关传入的参数的任何信息。

Object.prototype.toString.call(null);
=> [object Null]

Object.prototype.toString.call(undefined);
=> [object Undefined]

由于nulland undefinedare not objects (and failed CheckObjectCoercible),“object”部分真的,真的看起来毫无意义。

我不得不认为最初将“对象”部分放在那里是有原因的,即使从那以后这个原因已经丢失了,现在只是出于历史原因而保留了下来。

任何人都可以帮助阐明这一点吗?


需要明确的是,我已经知道如何Object.prototype.toString用于获取[[Class]]对象的(类型)。我的问题涉及返回字符串格式的原因——特别是开头的“对象”部分。我想知道这部分是否有原因,或者这部分是否有可能的未来原因。也许将来它可以返回“对象”以外的东西?我可以期望它总是返回“对象”吗?如果是这样,为什么它甚至返回它?无论输入是什么,谁想要一个函数总是返回相同的东西?

4

3 回答 3

3

ES5.1 规范的附件 F 说明了这一点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 异常。这个异常破坏了一些现有的代码,所以我们必须修复规范以在这种情况下不抛出。

那么toStringnull 和 undefined 应该返回什么?事实证明,许多现有代码还期望Object.prototype.toString总是返回一个格式为 的字符串"[object *]"。所以,我们决定让 null 和 undefined 产生"[object Null]"and "[object Undefined]"

这似乎奏效了,并且通常允许现有的基于 ES3 的代码在 ES5/5.1 中与严格模式相关的更改存在的情况下继续工作。

于 2012-11-01T06:05:50.457 回答
2

Okay, think of it like this:

  1. All values in JavaScript are actually instances of a class. Even undefined and null are implemented as singleton objects in the interpreter. For example undefined is actually Undefined.instance in Rhino (implemented in Java).
  2. The toString method defined exposes the class name of the JavaScript value. However since the value is not the class itself but an instance of the class, toString returns the a string of the form [object ClassName].
  3. Yes, the [object *] form is redundant. However someone wanted it to be like that and so we're stuck with it. Now that it's there it will cause a lot of problems if it's suddenly changed. Old code that depends upon it may break.

Edit: It's important to note when JavaScript ends and the interpreter begins. For example when you call a function in JavaScript the interpreter creates a new execution context, which is an object in the language in which the JavaScript interpreter is written (not JavaScript itself).

Similarly, the [[Class]] of a JavaScript value is the class in the language in which the JavaScript interpreter is written, which is used to create instances of that class. For example, in Rhino functions are instances of the class org.mozilla.javascript.BaseFunction. This class has a method called getClassName which returns Function (the [[Class]] of the instances of BaseFunction).

Similarly there's a class called org.mozilla.javascript.Undefined which has a static property called instance which is the singleton instance of Undefined.

于 2012-10-31T05:49:12.950 回答
1

这是 ES5 所说的:

15.2.4.2 Object.prototype.toString()

当调用 toString 方法时,会执行以下步骤:

  1. 如果 this 值未定义,则返回“[object Undefined]”。
  2. 如果 this 值为 null,则返回“[object Null]”。
  3. 令 O 为调用 ToObject 并将 this 值作为参数传递的结果。
  4. 令 class 为 O 的 [[Class]] 内部属性的值。
  5. 返回作为连接三个字符串“[object”、class 和“]”的结果的 String 值。

所以toString首先处理undefinedand 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 的主要目标是简单。松散的打字让生活更轻松,但这也意味着有一些弱点需要学习。

于 2012-10-31T07:11:40.013 回答