扩展本机JavaScript Error构造函数

时间:2013-01-14 11:23:30

标签: javascript error-handling try-catch custom-error-handling

我尝试通过Error构造函数原型的扩展来扩展JavaScript错误属性:

<script type="text/javascript">
// extending the Error properties to all the ones available in the various browsers:
Error.prototype = {
    name: null, // (all browsers); the name of the error
    message: null, // (all browsers); the error message as a string
    description: null, // (Internet Explorer); description of the error
    fileName: null, // (Firefox); the name of the file where the error occurred
    lineNumber: null, // (Firefox); the number of line where the error occurred
    columnNumber: null, // (Firefox); the number of column where the error occurred
    number: null, // (Internet Explorer); the error code as a number
    stack: null // (Firefox, Chrome); detailed information about the location where the error exactly occurred
};

function log(error) {
    var errors = [];

    for (var prop in error) {
        errors.push(prop + ': ' + error[prop]);
    }

    alert(errors.join('\n'));
}
</script>

然后我测试了日志功能:

<script type="text/javascript>
try {
    var a = b; // b is undefined!
} catch(error) {
    log(error);
}
</script>

结果是错误对象只显示了一些属性(例如在Firefox fileNamelineNumbercolumnNumber上),就好像它没有被扩展一样。

但最奇怪的是,for...in周期似乎无法遍历所有错误对象属性:尝试提醒标准属性error.message通常会返回一条消息。

所以我的测试结果是:

  1. 错误构造函数不能通过其原型进行扩展,因为其他本机构造函数是;
  2. for...in循环无法遍历错误对象的属性。
  3. 我是对的吗? 是否有一些有趣的证据/资源,您可能会建议您更多地了解它?

1 个答案:

答案 0 :(得分:0)

一个。就像,Raynos说的那样,message没有被设置的原因是Error是一个函数,它返回一个新的Error对象并且操纵this in无论如何。

B中。这样做的方法是从构造函数返回apply的结果,以及以通常复杂的javascripty方式设置原型:

function MyError() {
    var tmp = Error.apply(this, arguments);
    tmp.name = this.name = 'MyError'

    this.stack = tmp.stack
    this.message = tmp.message

    return this
}
    var IntermediateInheritor = function() {}
        IntermediateInheritor.prototype = Error.prototype;
    MyError.prototype = new IntermediateInheritor()

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 ...>

此时这种方式的唯一问题(我已经过了一点)是

  • stackmessage以外的其他属性未包含在MyError
  • stacktrace有一个额外的行,这不是必需的。

第一个问题可以通过使用此答案中的技巧迭代所有不可枚举的错误属性来修复:Is it possible to get the non-enumerable inherited property names of an object?,但是不支持ie&lt; 9。第二个问题可以通过撕掉堆栈跟踪中的那条线来解决,但我不确定如何安全地执行此操作(可能只是删除了第二行的e.stack.toString()??)。