在JS中,似乎无法检查传递给函数的参数是否实际上是'error'类型或Error实例。
例如,这是无效的:
typeof err === 'error'
因为只有6种可能的类型(以字符串形式):
typeof运算符以字符串形式返回类型信息。有六个可能的值typeof
返回:
“数字”,“字符串”,“布尔”,“对象”,“函数”和“未定义”。
但是,如果我有一个简单的用例,例如:
function errorHandler(err) {
if (typeof err === 'error') {
throw err;
}
else {
console.error('Unexpectedly, no error was passed to error handler. But here is the message:',err);
}
}
那么确定参数是否为Error实例的最佳方法是什么?
对instanceof
操作员有帮助吗?
您可以使用instanceof
运算符(但请参见下面的警告!)。
var myError = new Error('foo');
myError instanceof Error // true
var myString = "Whatever";
myString instanceof Error // false
如果错误是在与进行检查的位置不同的窗口/框架/ iframe中引发的,则上述方法将无效。在这种情况下,instanceof Error
即使对于Error
对象,检查也将返回false 。在这种情况下,最简单的方法是鸭式打字。
if (myError && myError.stack && myError.message) {
// it's an error, probably
}
但是,如果您有包含stack
和message
属性的非错误对象,则鸭子式输入可能会产生误报。
我问了最初的问题-@Trott的回答肯定是最好的。
但是,由于JS是一种动态语言,并且有许多JS运行时环境,所以instanceof
操作员在跨越iframe等边界时尤其会在前端开发中失败。参见:https :
//github.com/mrdoob/three.js/issues/5886
如果您可以使用鸭子输入,那么应该很好:
let isError = function(e){
return e && e.stack && e.message;
}
我个人更喜欢静态类型的语言,但是如果您使用的是动态语言,则最好采用动态语言,而不要强制其表现为静态类型的语言。
如果您想更精确一点,可以这样做:
let isError = function(e){
return e && e.stack && e.message && typeof e.stack === 'string'
&& typeof e.message === 'string';
}
var myError = new Error('foo');
myError instanceof Error // true
var myString = "Whatever";
myString instanceof Error // false
唯一的问题是
myError instanceof Object // true
替代方法是使用构造函数属性。
myError.constructor === Object // false
myError.constructor === String // false
myError.constructor === Boolean // false
myError.constructor === Symbol // false
myError.constructor === Function // false
myError.constructor === Error // true
尽管应注意,此匹配非常具体,例如:
myError.constructor === TypeError // false
您可以Object.prototype.toString
轻松地检查对象是否为Error
,这也适用于不同的帧。
function isError(obj){
return Object.prototype.toString.call(obj) === "[object Error]";
}
function isError(obj){
return Object.prototype.toString.call(obj) === "[object Error]";
}
console.log("Error:", isError(new Error));
console.log("RangeError:", isError(new RangeError));
console.log("SyntaxError:", isError(new SyntaxError));
console.log("Object:", isError({}));
console.log("Array:", isError([]));
您可以使用obj.constructor.name来检查对象的“类” https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/name#Function_names_in_classes
例如
var error = new Error("ValidationError");
console.log(error.constructor.name);
上一行将记录“ Error”,它是对象的类名称。如果该类未使用名称为“ name”的属性,则可以与javascript中的任何类一起使用
感谢@Trott提供的代码,我只是使用了相同的代码,并添加了一个实时工作的示例,以使他人受益。
<html>
<body >
<p>The **instanceof** operator returns true if the specified object is an instance of the specified object.</p>
<script>
var myError = new Error("TypeError: Cannot set property 'innerHTML' of null"); // error type when element is not defined
myError instanceof Error // true
function test(){
var v1 = document.getElementById("myid").innerHTML ="zunu"; // to change with this
try {
var v1 = document.getElementById("myidd").innerHTML ="zunu"; // exception caught
}
catch (e) {
if (e instanceof Error) {
console.error(e.name + ': ' + e.message) // error will be displayed at browser console
}
}
finally{
var v1 = document.getElementById("myid").innerHTML ="Text Changed to Zunu"; // finally innerHTML changed to this.
}
}
</script>
<p id="myid">This text will change</p>
<input type="button" onclick="test();">
</body>
</html>
Or use this for different types of errors
function isError(val) {
return (!!val && typeof val === 'object')
&& ((Object.prototype.toString.call(val) === '[object Error]')
|| (typeof val.message === 'string' && typeof val.name === 'string'))
}
文章标签:javascript , node.js
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!
评论已关闭!