【问题标题】:Where does an object's toString method get its value from?一个对象的 toString 方法从哪里得到它的值?
【发布时间】:2015-02-15 15:31:52
【问题描述】:

我正在用 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 对象还是其他东西?

【问题讨论】:

  • 你想达到什么目的?
  • 阅读es5.github.io/#x15.2.4.2es5.github.io/#x8.6.2。那些“类”名称应该只用于宿主对象,对于纯 JS 的所有内容(例如您的MyClass),值“对象”是合适的。
  • 如果你想为每个“类”覆盖 toString 方法,你应该使用一个“类助手”来创建构造函数并自动连接它们的原型链。如果你的程序中有很多“类”,这是值得做的。

标签: javascript class inheritance prototype


【解决方案1】:

当你使用...

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.2Object.prototype.toString()

toString方法被调用时,执行如下步骤:

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

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

因此,

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

    8.6.2对象内部属性和方法

    本规范未定义 ECMAScript 语言运算符或 允许程序修改对象的内置函数 [[Class]] 或 [[Prototype]] 内部属性

【讨论】:

  • 这就是我想知道的。如果我想要更多描述性的 toString 方法,我想我只需要坚持重写原型方法。谢谢!
猜你喜欢
  • 2017-07-22
  • 1970-01-01
  • 1970-01-01
  • 2016-09-16
  • 1970-01-01
  • 2012-07-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多