对象的 toString 方法从哪里获取它的值?

Where does an object's toString method get its value from?

我正在 JavaScript 中编写一些自定义 classes,我希望他们的 toString 方法能够 return 反映 class 的值本身而不是对象 class。例如:

function MyClass(){}

var my_object=new MyClass();
alert(my_object);// Returns "[object Object]"

如果我实例化 HTMLImageElement,结果会有所不同:

var my_image=new Image();
alert(my_image);// Returns "[object HTMLImageElement]"

我可以像这样重写自定义 class 的 toString 方法:

MyClass.prototype={
    toString:function(){
        return "[object MyClass]";
    }
};

重写 toString 方法允许我得到反映我的 class 名称的结果,但我觉得这种方法与 HTMLImageElement 使用的方法不同。是吗?有没有办法在不覆盖原型的情况下更改 toString 的结果?是内置 class 类的 HTMLImageElement 实际上 JavaScript 对象还是其他东西?

当您使用...

function MyClass(){}
var my_object = new MyClass();

... my_object.toString 继承自 Object.prototype:

my_object.hasOwnProperty('toString');                      // false
MyClass.prototype.hasOwnProperty('toString');              // false
Object.prototype.hasOwnProperty('toString');               // true
/* => */ my_object.toString === Object.prototype.toString; // true

Image 个实例的情况下,它们也从 Object.prototype 继承 toString

var my_image = new Image();
my_image.hasOwnProperty('toString');                      // false
HTMLImageElement.prototype.hasOwnProperty('toString');    // false
HTMLElement.prototype.hasOwnProperty('toString');         // false
Node.prototype.hasOwnProperty('toString');                // false
EventTarget.prototype.hasOwnProperty('toString');         // false
Object.prototype.hasOwnProperty('toString');              // true
/* => */ my_image.toString === Object.prototype.toString; // true

Object.prototype.toString 定义为

15.2.4.2 Object.prototype.toString ( )

When the toString method is called, the following steps are taken:

  1. If the this value is undefined, return "[object Undefined]".
  2. If the this value is null, return "[object Null]".
  3. Let O be the result of calling ToObject passing the this value as the argument.
  4. Let class be the value of the [[Class]] internal property of O.
  5. Return the String value that is the result of concatenating the three Strings "[object ", class, and "]".

区别在于my_object的内部[[Class]]是"Object",而[=36=的内部[[Class]] ] 是 "HTMLImageElement".

因此,

  • 不,HTMLImageElement 不会通过覆盖 Object.prototype.toString 来生成自定义字符串,而是使用自定义 [[Class]]。
  • 但您不能使用相同的方法,至少在 ECMAScript 5 中:

    8.6.2 Object Internal Properties and Methods

    This specification defines no ECMAScript language operators or built-in functions that permit a program to modify an object’s [[Class]] or [[Prototype]] internal properties