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

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

本文关键字:获取 toString 方法 对象      更新时间:2023-11-05

我正在用JavaScript编写一些自定义类,我希望他们的toString方法返回一个反映类本身而不是Object类的值。例如:

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]"

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

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

重写 toString 方法允许我获得反映我的类名的结果,但我觉得这种方法与 HTMLImageElement 使用的方法不同。是吗?有没有办法在不覆盖原型中覆盖toString的结果的情况下更改它?像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 对象原型到字符串 ( (

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

  1. 如果this值为 undefined ,则返回 "[object Undefined]"
  2. 如果this值为 null ,则返回 "[object Null]"
  3. O是调用ToObject传递this值作为参数的结果。
  4. class O 的 [[类]] 内部属性的值。
  5. 返回字符串值,该值是连接三个字符串的结果 "[object "class"]"

区别在于my_object的内部[[类]]是"Object",但my_image的内部[[类]]是"HTMLImageElement"的。

因此

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

    8.6.2 对象内部属性和方法

    此规范没有定义 ECMAScript 语言运算符或 允许程序修改对象的内置函数 [[类]] 或 [[原型]] 内部属性