检查JS

时间:2015-05-26 21:27:58

标签: javascript node.js

在JS中,似乎无法检查传递给函数的参数是否实际上是类型'错误'或错误的实例。

例如,这是无效的:

typeof err === 'error'

因为只有6种可能的类型(以字符串的形式):

typeof运算符将类型信息作为字符串返回。 typeof返回有六个可能的值:

  

" number"," string"," boolean"," object"," function"和" undefined"。

MSDN

但是如果我有一个这样简单的用例怎么办:

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运算符吗?

10 个答案:

答案 0 :(得分:173)

您可以使用instanceof运算符。

var myError = new Error('foo');
myError instanceof Error // true
var myString = "Whatever";
myString instanceof Error // false

如果在不同的窗口/框架/ iframe中抛出错误而不是检查发生的位置,则无法工作。但这是一种简单且相对稳健的方法。

答案 1 :(得分:18)

我问了原来的问题 - @ 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';
    }

答案 2 :(得分:5)

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

答案 3 :(得分:3)

您可以使用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([]));

此行为由ECMAScript语言规范保证。

Object.prototype.toString

调用toString方法时,将执行以下步骤:

  1. 如果此值不确定,则返回“ [object Undefined]”。
  2. 如果此值为null,则返回“ [object Null]”。
  3. 让O成为调用ToObject并将此值作为参数传递的结果。
  4. 让class为O的[[Class]]内部属性的值。
  5. 返回字符串值,该值是将三个字符串“ [object”,class和“]”串联而成的。

Properties of Error Instances

Error实例从Error原型对象继承属性,并且它们的[[Class]]内部属性值为“ Error”。错误实例没有特殊属性。

答案 4 :(得分:1)

感谢@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>

答案 5 :(得分:1)

对于那些正在寻找某种“官方”方式(就像我一样)的人来说,这是what MDN recommends

try {
  myRoutine();
} catch (e) {
  if (e instanceof RangeError) {
    // statements to handle this very common expected error
  } else {
    throw e;  // re-throw the error unchanged
  }
}

答案 6 :(得分:0)

或者将其用于不同类型的错误

function isError(val) {
  return (!!val && typeof val === 'object')
    && ((Object.prototype.toString.call(val) === '[object Error]')
      || (typeof val.message === 'string' && typeof val.name === 'string'))
}

答案 7 :(得分:0)

您可以使用obj.constructor.name来检查对象https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name#Function_names_in_classes的“类”

例如

var error = new Error("ValidationError");
console.log(error.constructor.name);

上面的行将记录“错误”,它是对象的类名称。如果该类未使用名称为“ name”的属性

,则可以与javascript中的任何类一起使用

答案 8 :(得分:0)

只需使用 error.name

function _err(type = false) {
    if(type) {
        throw new TypeError('Oh crap!')
    }
    throw new Error('Oh crap!')
}

try {
    _err(true)
} catch (error) {
    console.log(typeof error.name, error.name, error.name === 'TypeError')
}

try {
    _err()
} catch (error) {
    console.log(typeof error.name, error.name, error.name === 'Error')
}

答案 9 :(得分:0)

您可以进一步从@iota 获取答案,并通过 [[Prototype]] 或已弃用的 getPrototypeOf() 属性检查测试对象的内部 __proto__ 属性。

如果对象是错误的,它继承自Error.prototype。所以也许是这样的:

// the object you want to check 
const objectToCheck = new Error();

// current way
console.log(Object.getPrototypeOf(objectToCheck) === Error.prototype);  /* true*/

// deprecated way
console.log(objectToCheck.__proto__ === Error.prototype);  /* true */