我在Javascript中定义自定义错误对象时发现了一个奇怪的行为:
function MyError(msg) {
Error.call(this, msg);
this.name = "MyError";
}
MyError.prototype.__proto__ = Error.prototype;
var error = new Error("message");
error.message; // "message"
var myError = new MyError("message");
myError instanceof Error; // true
myError.message; // "" !
Run Code Online (Sandbox Code Playgroud)
为什么new Error("message")
设置message
属性,而Error.call(this, msg);
不是?当然,我可以this.message = msg
在MyError
构造函数中定义,但我不太明白为什么它还没有设置在第一位.
B T*_*B T 38
A.像,Raynos说,之所以message
没有被设置的是Error
是返回一个新的Error对象和它的功能不操作this
以任何方式.
B.正确执行此操作的方法是从构造函数设置apply的结果this
,以及以通常复杂的javascripty方式设置原型:
function MyError() {
var tmp = Error.apply(this, arguments)
tmp.name = this.name = 'MyError'
this.message = tmp.message
// instead of this.stack = ..., a getter for more optimizy goodness
Object.defineProperty(this, 'stack', {
get: function () {
return tmp.stack
}
})
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 ...>
Run Code Online (Sandbox Code Playgroud)
这种方式在这一点上做的唯一问题(我已经稍微改了一下)就是这样
stack
和message
不包括的属性MyError
,和第一个问题可以通过使用此答案中的技巧迭代错误的所有非可枚举属性来修复:是否可以获取对象的不可枚举的继承属性名称?,但<9不支持.第二个问题可以通过撕掉堆栈跟踪中的那条线来解决,但我不确定如何安全地做到这一点(可能只是删除了第二行的e.stack.toString()??).
更新
我创建了一个继承库来执行此操作^ https://github.com/fresheneesz/proto
Ray*_*nos 16
function MyError(msg) {
var err = Error.call(this, msg);
err.name = "MyError";
return err;
}
Run Code Online (Sandbox Code Playgroud)
Error
如果不操作this
,它会创建一个返回的新错误对象.这就是为什么Error("foo")
没有new
关键字的原因.
请注意,这是特定于实现的,v8(chrome&node.js)的行为与此类似.
也是MyError.prototype.__proto__ = Error.prototype;
一种不好的做法.使用
MyError.prototype = Object.create(Error.prototype, {
constructor: { value: MyError }
});
Run Code Online (Sandbox Code Playgroud)
在Node.js中,您可以创建如下自定义错误:
var util = require('util');
function MyError(message) {
this.message = message;
Error.captureStackTrace(this, MyError);
}
util.inherits(MyError, Error);
MyError.prototype.name = 'MyError';
Run Code Online (Sandbox Code Playgroud)
请参阅节点文档中的captureStackTrace
归档时间: |
|
查看次数: |
16115 次 |
最近记录: |