6

我正在开发一个小型 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!

我已经在此处MDN上阅读过有关此的文章,但所有人都说我要使用以下内容:

var MyError = function(msg){
    this.message = msg;
};

但我的问题是 - 如果不在 Error 的构造函数中,那么消息在哪里初始化?可能有人知道 Error 本机构造函数是如何工作的?

谢谢!

PS 如果有趣的话——我正在开发Enum.js库。

4

1 回答 1

5

你在做什么很好。这就是Error问题所在。

在这条线上:

Error.prototype.constructor.apply(this, arguments);

...您将Error(间接)作为普通函数调用而不是作为new表达式的一部分进行调用,并且当您将其作为非构造函数调用时的定义行为Error是创建一个新的空白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拒绝玩球,您的选择会有点有限......

于 2013-07-08T15:52:26.880 回答