Angular打印错误的minErr函数
Wscats opened this issue · 1 comments
angular minErr函数的源码是这样的,这个函数主要用来输出错误的提示信息
function minErr(module) {
return function() {
var message, i, code = arguments[0],
prefix = "[" + (module ? module + ":" : "") + code + "] ",
template = arguments[1],
templateArgs = arguments,
stringify = function(obj) {
return "function" == typeof obj ? obj.toString().replace(/ \{[\s\S]*$/, "") : "undefined" == typeof obj ? "undefined" : "string" != typeof obj ? JSON.stringify(obj) : obj
};
for (message = prefix + template.replace(/\{\d+\}/g, function(match) {
var arg, index = +match.slice(1, -1);
return index + 2 < templateArgs.length ? (arg = templateArgs[index + 2], "function" == typeof arg ? arg.toString().replace(/ ?\{[\s\S]*$/, "") : "undefined" == typeof arg ? "undefined" : "string" != typeof arg ? toJson(arg) : arg) : match
}), message = message + "\nhttp://errors.angularjs.org/1.2.1/" + (module ? module + "/" : "") + code, i = 2; i < arguments.length; i++) message = message + (2 == i ? "?" : "&") + "p" + (i - 2) + "=" + encodeURIComponent(stringify(arguments[i]));
return new Error(message)
}
}
从这个函数中可以学到几点东西
首先是里面这个正则
template.replace(/\{\d+\}/g)
这个正则是匹配所有"{1个或更多数字}"形式的字符串
例如
var a = "{1}233{2}";
message = a.replace(/(\{)(\d+)(\})/g, 'wscats');//加了括号方便理解
相当于
new RegExp("\{\d+\}", "g")//g代表 global match(全定匹配)
其次是return new Error(message),这个
ngMinErr = minErr("ng");
throw ngMinErr("badname","hasOwnProperty is not a valid {0} name","module");
抛出打印的异常
function checkInput(x) {
try {
if (isNaN(parseInt(x))) {
throw new Error("Input is not a number.");
}
} catch (e) {
document.write(e.description);
console.log(new Error("Input is not a number."));
}
}
checkInput("not a number");
输出如下的异常信息
Uncaught Error: [ng:badname] hasOwnProperty is not a valid module name
http://errors.angularjs.org/1.2.1/ng/badname?p0=module"
这里如果throw new Error("wscats");之后,后面的代码就会得不到执行
无意之中看到了一篇文章
http://my.oschina.net/myprogworld/blog/207692
在1.2.5的版本中这里的第一个函数是这样写的
function minErr(module) {
return function () {
var code = arguments[0],
prefix = '[' + (module ? module + ':' : '') + code + '] ',
template = arguments[1],
templateArgs = arguments,
stringify = function (obj) {
if (typeof obj === 'function') {
return obj.toString().replace(/ \{[\s\S]*$/, '');
} else if (typeof obj === 'undefined') {
return 'undefined';
} else if (typeof obj !== 'string') {
return JSON.stringify(obj);
}
return obj;
},
message, i;
message = prefix + template.replace(/\{\d+\}/g, function (match) {
var index = +match.slice(1, -1), arg;
if (index + 2 < templateArgs.length) {
arg = templateArgs[index + 2];
if (typeof arg === 'function') {
return arg.toString().replace(/ ?\{[\s\S]*$/, '');
} else if (typeof arg === 'undefined') {
return 'undefined';
} else if (typeof arg !== 'string') {
return toJson(arg);
}
return arg;
}
return match;
});
message = message + '\nhttp://errors.angularjs.org/1.2.5/' +
(module ? module + '/' : '') + code;
for (i = 2; i < arguments.length; i++) {
message = message + (i == 2 ? '?' : '&') + 'p' + (i-2) + '=' +
encodeURIComponent(stringify(arguments[i]));
}
return new Error(message);
};
}
其实区别只是在于把message = prefix + template.replace(/{\d+}/g...这段放在for里面而已,其实我是喜欢1.2.5这一段代码的写法,因为比较清晰明了
而后面angular调用这个方法会根据传的是两个参数还是三个参数进行打印
例如这样
throw ngMinErr("btstrpd", "App Already Bootstrapped with this Element '{0}'", tag)
这里面的{0}就会被代码中的正则处理了