javascript效仿java提供了异常机制,鼓励用异常来代替c时代的返回值判断,虽然javascript的throw语句可以后跟任何类型的表达式,但是规范情况下最好还是抛出Error以及Error子类的实例,自定义异常在javascript中利用原型链来模拟继承Error实现。
java的自定义异常类:
class CustomException extends Exception {
CustomException(String msg) {
super(msg);
}
}
那么理论上对应javascript的实现:
function CustomException() {
Error.apply(this,arguments);
}
function t(){}
t.prototype=Error.prototype;
CustomException.prototype=new t();
CustomException.prototype.name="CustomException";
CustomException.prototype.constructor=CustomException;
但是如果使用的话:
try{
throw new CustomException("test");
} catch(e){
if(e instanceof CustomException) {
alert(e.message);
}
}
会发现 message 属性并没有被设置到自定义异常实例上去,和java不同即Error构造器没有对当前实例进行初始化操作,参考 ecma规范:
When Error is called as a function rather than as a constructor, it creates and initialises a new Error object.
推测 Error 实现可能如下:
//返回native实例
function Error(msg){
//不等价 instanceof ,没有对应 js 操作
if(this 完全是 Error 实例 ) {
this.message=msg;
}
else
return new Error(msg)
}
Error.prototype=....
故和一般的继承模拟不一样:
function CustomException() {
var e=Error.apply(this,arguments);
//不等,this 对于 native Error函数不管用
console.log(e==this);
}
new CustomException("xx");
e !== this,所以这里 Error构造器的调用在自定义异常中就变的毫无意义,只能自己手动设置 message :
function CustomException(msg) {
//无意义
//Error.apply(this,arguments);
this.message=msg;
}
PS1:native Error 实例在各个浏览期间差异比较大,可执行console.dir(new Error("x"));测试,但是标准只有message和name两个属性。
PS2:对于其它内置类型(Array,Date ...)似乎也存在以上问题.
397

被折叠的 条评论
为什么被折叠?



