出于某种原因,在下面的代码段中,构造函数委托似乎不起作用:

function NotImplementedError() { 
  Error.apply(this, arguments); 
}
NotImplementedError.prototype = new Error();

var nie = new NotImplementedError("some message");
console.log("The message is: '"+nie.message+"'")

运行该命令得到的消息是:"。有什么想法,为什么,或者是否有更好的方法来创建一个新的错误子类?是否有一个问题,应用到本机错误构造函数,我不知道?


当前回答

更简单的方法。你可以让你的对象从Error对象继承。 例子:

function NotImplementError(message)
{
    this.message = message;
    Error.call();
    Error.call(message);
} 

我们所做的是使用函数call()调用Error类的构造函数,因此基本上与在其他面向对象语言中实现类继承是一样的。

其他回答

以上所有的答案都很糟糕,真的。即使是107个向上的那个!真正的答案在这里:

从Error对象继承- message属性在哪里?

TL; diana:

a .没有设置message的原因是Error是一个函数,它返回一个新的Error对象,并且不以任何方式操作它。

B.正确的方法是从构造函数返回apply的结果,以及以通常复杂的javascript方式设置原型:

function MyError() { var temp = Error.apply(this, arguments); temp.name = this.name = 'MyError'; this.message = temp.message; if(Object.defineProperty) { // getter for more optimizy goodness /*this.stack = */Object.defineProperty(this, 'stack', { get: function() { return temp.stack }, configurable: true // so you can change it if you want }) } else { this.stack = temp.stack } } //inherit prototype using ECMAScript 5 (IE 9+) MyError.prototype = Object.create(Error.prototype, { constructor: { value: MyError, writable: true, configurable: true } }); var myError = new MyError("message"); console.log("The message is: '" + myError.message + "'"); // The message is: 'message' console.log(myError instanceof Error); // true console.log(myError instanceof MyError); // true console.log(myError.toString()); // MyError: message console.log(myError.stack); // MyError: message \n // <stack trace ...> //for EMCAScript 4 or ealier (IE 8 or ealier), inherit prototype this way instead of above code: /* var IntermediateInheritor = function() {}; IntermediateInheritor.prototype = Error.prototype; MyError.prototype = new IntermediateInheritor(); */

您可能会使用一些技巧来枚举tmp Error的所有不可枚举属性来设置它们,而不是显式地只设置stack和message,但是ie<9不支持这种技巧

这在Cesium DeveloperError中很好地实现了:

文档 源

它的简化形式是:

var NotImplementedError = function(message) {
    this.name = 'NotImplementedError';
    this.message = message;
    this.stack = (new Error()).stack;
}

// Later on...

throw new NotImplementedError();

如果你使用Node/Chrome。下面的代码片段将为您提供满足以下要求的扩展。

err instanceof Error err instanceof CustomErrorType console.log() returns [CustomErrorType] when created with a message console.log() returns [CustomErrorType: message] when created without a message throw/stack provides the information at the point the error was created. Works optimally in Node.JS, and Chrome. Will pass instanceof checks in Chrome, Safari, Firefox and IE 8+, but will not have a valid stack outside of Chrome/Safari. I'm OK with that because I can debug in chrome, but code which requires specific error types will still function cross browser. If you need Node only you can easily remove the if statements and you're good to go.

片段

var CustomErrorType = function(message) {
    if (Object.defineProperty) {
        Object.defineProperty(this, "message", {
            value : message || "",
            enumerable : false
        });
    } else {
        this.message = message;
    }

    if (Error.captureStackTrace) {
        Error.captureStackTrace(this, CustomErrorType);
    }
}

CustomErrorType.prototype = new Error();
CustomErrorType.prototype.name = "CustomErrorType";

使用

var err = new CustomErrorType("foo");

输出

var err = new CustomErrorType("foo");
console.log(err);
console.log(err.stack);

[CustomErrorType: foo]
CustomErrorType: foo
    at Object.<anonymous> (/errorTest.js:27:12)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Function.Module.runMain (module.js:497:10)
    at startup (node.js:119:16)
    at node.js:906:3

/errorTest.js:30
        throw err;
              ^
CustomErrorType: foo
    at Object.<anonymous> (/errorTest.js:27:12)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Function.Module.runMain (module.js:497:10)
    at startup (node.js:119:16)
    at node.js:906:3

我也遇到过类似的问题。我的错误需要是error和NotImplemented的实例,它还需要在控制台中产生一致的回溯。

我的解决方案:

var NotImplemented = (function() {
  var NotImplemented, err;
  NotImplemented = (function() {
    function NotImplemented(message) {
      var err;
      err = new Error(message);
      err.name = "NotImplemented";
      this.message = err.message;
      if (err.stack) this.stack = err.stack;
    }
    return NotImplemented;
  })();
  err = new Error();
  err.name = "NotImplemented";
  NotImplemented.prototype = err;

  return NotImplemented;
}).call(this);

// TEST:
console.log("instanceof Error: " + (new NotImplemented() instanceof Error));
console.log("instanceof NotImplemented: " + (new NotImplemented() instanceofNotImplemented));
console.log("message: "+(new NotImplemented('I was too busy').message));
throw new NotImplemented("just didn't feel like it");

使用node.js运行的结果:

instanceof Error: true
instanceof NotImplemented: true
message: I was too busy

/private/tmp/t.js:24
throw new NotImplemented("just didn't feel like it");
      ^
NotImplemented: just didn't feel like it
    at Error.NotImplemented (/Users/colin/projects/gems/jax/t.js:6:13)
    at Object.<anonymous> (/Users/colin/projects/gems/jax/t.js:24:7)
    at Module._compile (module.js:449:26)
    at Object.Module._extensions..js (module.js:467:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Module.runMain (module.js:487:10)
    at process.startup.processNextTick.process._tickCallback (node.js:244:9)

该错误通过了我的所有3个标准,尽管stack属性是非标准的,但在大多数较新的浏览器中都支持它,这在我的情况下是可以接受的。

以下是Mozilla官方文档中的错误。

function NotImplementedError(message) {
    var instance = new Error(message);
    instance.name = 'NotImplementedError';

    Object.setPrototypeOf(instance, Object.getPrototypeOf(this));
    if (Error.captureStackTrace) {
        Error.captureStackTrace(instance, NotImplementedError);
    }
    return instance;
}

NotImplementedError.prototype = Object.create(Error.prototype, {
    constructor: {
        value: Error,
        enumerable: false,
        writable: true,
        configurable: true
    }
});