如何在Javascript中检测使用`in`运算符是否安全?

时间:2016-04-27 00:52:37

标签: javascript

本声明

 if ('foo' in bar)
如果bar是字符串,

会抛出TypeError。我认为对于其他类型的对象可能会有相同的错误。

如何判断bar是否是支持in运算符的对象?

这段代码是不够的:如果foo是一个字符串,它会传递给in语句并抛出。

if (foo instanceof Object && ! (foo instanceof String))
{
    if ('foo' in foo) {}
}

4 个答案:

答案 0 :(得分:2)

in operator抛出TypeError是右操作数不是对象。

您可以使用

检查值是否为对象
Object(value) === value;

此外,in运算符调用内部[[HasProperty]]方法。 For ordinary objects it should never throw,但在一些奇特的物体中可能就是这种情况。例如,

var proxy = new Proxy({}, {has: () => {throw "Can't use `in`"}});
"property" in proxy; // Error: Can't use `in`

为了处理这些情况,我认为您只能使用try语句ringø suggested

答案 1 :(得分:0)

var o = {};

console.log(o.constructor === Object && o !== null); //true

答案 2 :(得分:0)

捕获任何错误

try { 
   if ('foo' in bar) { 
   }
}
catch(e) {
   // 'foo' is not in bar
}

或者如果您只想捕捉 'foo' in bar 错误

var inbar = false;
try { if ('foo' in bar) inbar = true; } 
catch(e) {}

if (inbar) {
   ...
}

答案 3 :(得分:0)

  

如何检测在Javascript中使用in运算符是否安全?

From the ES5 spec

  

ShiftExpression中的生产RelationalExpression:RelationalExpression评估如下:

     
      
  1. 让lref成为评估RelationalExpression的结果。
  2.   
  3. 让lval成为GetValue(lref)。
  4.   
  5. 让rref成为评估ShiftExpression的结果。
  6.   
  7. 让rval为GetValue(rref)。
  8.   
  9. 如果Type(rval)不是Object,则抛出TypeError异常。
  10.   
  11. 使用参数ToString(lval)返回调用[[HasProperty]] rval内部方法的结果。
  12.   

强调我的。

在ES5 Type()中可以

  • 未定义
  • 布尔
  • 字符串
  • 对象

为防止TypeError发生,您必须确保

  • undefined
  • null
  • truefalse
  • 任何字符串值
  • 任何数字值

EcmaScript 2015也引入了Symbol类型。

示例函数可能如下所示:

function canCallIn(arg) {
    if (arg === null ||
        arg === undefined)
        return false;
    switch (typeof arg) {
        case 'boolean':
        case 'string':
        case 'symbol':
        case 'number':
            return false;
    }
    return true;
}

虽然您可以进行各种优化。