我正在开发一个小型JS库,并在那里使用自定义错误例外。
所以,我决定以这种方式从原生Javascript Error对象继承它们(ORLY?):
var MyError = function(){
Error.prototype.constructor.apply(this, arguments);
};
// Inherit without instantiating Error
var Surrogate = function(){};
Surrogate.prototype = Error.prototype;
MyError.prototype = new Surrogate();
// Add some original methods
MyError.prototype.uniqueMethod = function(){...}
看起来像通常的继承..但是!
var err = new MyError("hello! this is text!");
console.log(err.message); // is giving me empty string!
我已阅读有关此here和MDN的文章,但所有人都说我要使用这样的内容:
var MyError = function(msg){
this.message = msg;
};
但我的问题是 - 如果不是在Error的构造函数中,那么消息初始化的地方? 可能有人知道Error本机构造函数是如何工作的吗?
谢谢!
P.S。如果它很有趣 - 我正在开发Enum.js库。
答案 0 :(得分:5)
你做得很好。这是Error
问题。
在这一行:
Error.prototype.constructor.apply(this, arguments);
...您正在调用Error
(间接)作为普通函数调用,而不是new
表达式的一部分,defined behavior for Error
when you call it as a non-constructor function是创建一个新的空白Error
并将其返回(而不是填充this
)。
现在,在正常情况下,您正在使用原型进行标准检查是否将其作为构造函数(if (this instanceof Error)
)工作。不幸的是,它似乎并没有这样做,并且无论用什么检查来确定它的调用方式似乎都没有立即服从你想要做的事情。即使这样(这只是一个测试,并不意味着你实际上是这样做的):
MyError.prototype = Error.prototype; // You wouldn't normally do this, it's just a test
......没有解决它。
This answer to another Stack Overflow question指向可能的解决方法(基本上,让Error
创建对象,然后从MyError
返回):
function MyError(message) {
var e = new Error(message);
// ...apply your enhancements to `e`
return e;
}
并不令人惊讶地满足,因为你必须将你的扩展直接放在对象而不是使用原型链,但如果Error
拒绝玩球,你的选择有点受限......