Javascript 检查 JS 中的 typeof 错误
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/30469261/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
checking for typeof error in JS
提问by Alexander Mills
In JS it doesn't seem possible to check if an argument passed to a function is actually of the type 'error' or an instance of Error.
在 JS 中,似乎无法检查传递给函数的参数实际上是“错误”类型还是 Error 的实例。
For example, this is not valid:
例如,这是无效的:
typeof err === 'error'
typeof err === 'error'
since there are only 6 possible types (in the form of strings):
因为只有 6 种可能的类型(以字符串的形式):
The typeof operator returns type information as a string. There are six possible values that typeofreturns:
typeof 运算符以字符串形式返回类型信息。有六个可能的typeof返回值:
"number", "string", "boolean", "object", "function" and "undefined".
“数字”、“字符串”、“布尔值”、“对象”、“函数”和“未定义”。
But what if I have a simple use case like this:
但是如果我有一个像这样的简单用例怎么办:
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);
}
}
so what is the best way to determine if an argument is an instance of Error?
那么确定参数是否为 Error 实例的最佳方法是什么?
is the instanceofoperator of any help?
是instanceof的任何帮助运营商?
回答by Trott
You can use the instanceofoperator (but see caveat below!).
您可以使用instanceof运算符(但请参阅下面的警告!)。
var myError = new Error('foo');
myError instanceof Error // true
var myString = "Whatever";
myString instanceof Error // false
The above won't work if the error was thrown in a different window/frame/iframe than where the check is happening. In that case, the instanceof Errorcheck will return false, even for an Errorobject. In that case, the easiest approach is duck-typing.
如果错误是在与检查发生位置不同的窗口/框架/iframe 中引发的,则上述方法将不起作用。在这种情况下,instanceof Error即使对于Error对象,检查也会返回 false 。在这种情况下,最简单的方法是鸭子类型。
if (myError && myError.stack && myError.message) {
// it's an error, probably
}
However, duck-typing may produce false positives if you have non-error objects that contain stackand messageproperties.
但是,如果您有包含stack和message属性的非错误对象,则鸭子类型可能会产生误报。
回答by Alexander Mills
I asked the original question - @Trott's answer is surely the best.
我问了最初的问题——@Trott 的回答肯定是最好的。
However with JS being a dynamic language and with there being so many JS runtime environments, the instanceofoperator can fail especially in front-end development when crossing boundaries such as iframes. See:
https://github.com/mrdoob/three.js/issues/5886
然而,由于 JS 是一种动态语言,并且有如此多的 JS 运行时环境,instanceof当跨越 iframe 等边界时,操作员可能会失败,尤其是在前端开发中。参见:https:
//github.com/mrdoob/three.js/issues/5886
If you are ok with duck typing, this should be good:
如果你对鸭子打字没问题,这应该很好:
let isError = function(e){
return e && e.stack && e.message;
}
I personally prefer statically typed languages, but if you are using a dynamic language, it's best to embrace a dynamic language for what it is, rather than force it to behave like a statically typed language.
我个人更喜欢静态类型语言,但如果您使用的是动态语言,最好就其本身而言采用动态语言,而不是强迫它表现得像静态类型语言。
if you wanted to get a little more precise, you could do this:
如果你想更精确一点,你可以这样做:
let isError = function(e){
return e && e.stack && e.message && typeof e.stack === 'string'
&& typeof e.message === 'string';
}
回答by Tom
var myError = new Error('foo');
myError instanceof Error // true
var myString = "Whatever";
myString instanceof Error // false
Only problem with this is
唯一的问题是
myError instanceof Object // true
An alternative to this would be to use the constructor property.
另一种方法是使用构造函数属性。
myError.constructor === Object // false
myError.constructor === String // false
myError.constructor === Boolean // false
myError.constructor === Symbol // false
myError.constructor === Function // false
myError.constructor === Error // true
Although it should be noted that this match is very specific, for example:
虽然需要注意的是,这个匹配是非常具体的,例如:
myError.constructor === TypeError // false
回答by persistent_poltergeist
You can use obj.constructor.name to check the "class" of an object https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name#Function_names_in_classes
您可以使用 obj.constructor.name 检查对象的“类” https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name#Function_names_in_classes
For Example
例如
var error = new Error("ValidationError");
console.log(error.constructor.name);
The above line will log "Error" which is the class name of the object. This could be used with any classes in javascript, if the class is not using a property that goes by the name "name"
上面的行将记录“错误”,它是对象的类名。如果该类不使用名称为“name”的属性,则这可以与 javascript 中的任何类一起使用
回答by Zabi Baig
Thanks @Trott for your code, I just used the same code and added with a real time working example for the benefit of others.
感谢@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>
回答by hev1
You can use Object.prototype.toStringto easily check if an object is an Error, which will work for different frames as well.
您可以使用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([]));
回答by Chris
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'))
}

