这绝对似乎是 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,并将this
set 设置为调用的原始对象[[Get]]
(此处为fe
对象)。
第二种情况很奇怪。似乎对的原型中的实例fe.toString()
执行了[[Get]]
for 。这似乎是错误的,因为步骤 5指定从函数中的值获取。"message"
Error
fe
Error.prototype.toString
message
this
toString
编辑
我之前认为这个问题是由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.message
fancy: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
。