6

私は小さな JS ライブラリを開発していて、そこでカスタム エラー例外を使用する予定でした。

そこで、ネイティブ Javascript エラー オブジェクトから次のように (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 ネイティブ コンストラクタがどのように機能するかを誰かが知っているのではないでしょうか?

ありがとう!

PS 興味深い場合 - 私はEnum.jsライブラリを開発していました。

4

1 に答える 1

5

あなたがしていることは問題ありません。それErrorこそが問題です。

この行で:

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

...式Errorの一部としてではなく、通常の関数呼び出しとして (間接的に)呼び出しており、コンストラクター以外の関数として呼び出した場合の定義済みの動作は、新しい空白を作成して返すことです (むしろ、移入よりも)。newErrorErrorthis

さて、通常の場合、プロトタイプで行っていることは、それがコンストラクタ ( ) として呼び出されたかどうかの標準チェックを行いif (this instanceof Error)ます。残念ながら、それはそうではないようです。また、それがどのように呼び出されたかを判断するために使用するチェックは、あなたがしようとしていることをすぐに受け入れられるようには見えません。これでも(これは単なるテストであり、実際に行うことを意図したものではありません):

MyError.prototype = Error.prototype; // You wouldn't normally do this, it's just a test

...解決しませんでした。

別のスタック オーバーフローの質問に対するこの回答は、考えられる回避策を示しています (基本的にError、オブジェクトを作成してからそれを返しますMyError)。

function MyError(message) {
    var e = new Error(message);
    // ...apply your enhancements to `e`
    return e;
}

プロトタイプチェーンを使用するのではなく、拡張機能をオブジェクトに直接配置する必要があるため、驚くほど満足できるものではありませんが、Errorボールをプレーすることを拒否した場合、オプションは少し制限されます...

于 2013-07-08T15:52:26.880 に答える