这绝对似乎是 Chrome 中的一个错误Error.prototype.toString:
var FancyError = function(x) { this.x = x; };
FancyError.prototype = new Error;
FancyError.prototype.x = "I'm the prototype";
Object.defineProperties(FancyError.prototype, {
'message': {
'get': function(){ return "fancy:" + this.x; }
}
});
var fe = new FancyError("I'm the instance");
在 Chrome 中使用此设置:
fe.message生产fancy:I'm the instance
fe.toString()生产Error: fancy:I'm the prototype
第一种情况发生的事情很容易理解:
fe.message使用参数提示调用[[Get]]onfe"message"
[[Get]]第 1 步获取在fe的原型上设置的访问器描述符(因为fe没有它自己的message属性)。
[[Get]]第 6 步调用访问器描述符上的 getter,并将thisset 设置为调用的原始对象[[Get]](此处为fe对象)。
第二种情况很奇怪。似乎对的原型中的实例fe.toString()执行了[[Get]]for 。这似乎是错误的,因为步骤 5指定从函数中的值获取。"message"ErrorfeError.prototype.toStringmessagethistoString
编辑
我之前认为这个问题是由fe它Error的原型链引起的。但是,考虑这种情况:
var FancyError = function(x) { this.x = x; };
FancyError.prototype.x = "I'm the prototype";
Object.defineProperties(FancyError.prototype, {
'message': {
'get': function(){ return "fancy:" + this.x; }
}
});
fe = new FancyError("I'm the instance");
在这种情况下:
fe.messagefancy:I'm the instance如上_
Error.prototype.toString.call(fe)是Error: fancy:I'm the prototype
因此,我们必须得出结论,ChromeError.prototype.toString错误地使用了包含 getter 的原型作为 的this值getter,这似乎与 的正常行为[[Get]]和/或第 5 步相矛盾Error.prototype.toString。