如何检测在Javascript中使用`in`运算符是否安全?
此声明如何检测在Javascript中使用`in`运算符是否安全?,javascript,Javascript,此声明 if ('foo' in bar) 如果bar是字符串,则抛出类型错误。我认为对于其他类型的对象也可能有相同的错误 如何判断bar是否是支持in运算符的对象 此代码不够:如果foo是一个字符串,它将传递到中的语句并抛出 if (foo instanceof Object && ! (foo instanceof String)) { if ('foo' in foo) {} } 抓住任何错误 try { if ('foo' in bar) {
if ('foo' in bar)
如果bar
是字符串,则抛出类型错误。我认为对于其他类型的对象也可能有相同的错误
如何判断bar
是否是支持in
运算符的对象
此代码不够:如果foo
是一个字符串,它将传递到中的语句并抛出
if (foo instanceof Object && ! (foo instanceof String))
{
if ('foo' in foo) {}
}
抓住任何错误
try {
if ('foo' in bar) {
}
}
catch(e) {
// 'foo' is not in bar
}
或者,如果您只想捕捉条形图中“foo”的错误
var inbar = false;
try { if ('foo' in bar) inbar = true; }
catch(e) {}
if (inbar) {
...
}
如果正确的操作数不是对象,则抛出TypeError
可以使用以下命令检查值是否为对象:
Object(value) === value;
此外,
中的运算符调用内部[[HasProperty]]方法,但在一些奇异的物体上可能就是这样。比如说,
var proxy = new Proxy({}, {has: () => {throw "Can't use `in`"}});
"property" in proxy; // Error: Can't use `in`
为了处理这些情况,我认为您只能使用try
语句,如下所示
如何检测在Javascript中使用中的运算符是否安全
生产RelationalExpression:ShiftePression中的RelationalExpression的计算如下:
设lref为计算RelationalExpression的结果
设lval为GetValue(lref)
设rref为计算移位压力的结果
设rval为GetValue(rref)
如果Type(rval)不是对象,则抛出TypeError异常。
返回使用参数ToString(lval)调用rval的[[HasProperty]]内部方法的结果
我的
在ES5中可以
- 未定义
- 空的
- 布尔值
- 串
- 数
- 反对
因此,为了防止发生TypeError
s,您必须确保它不会发生
未定义
null
true
或false
- 任何字符串值
- 任意数值
EcmaScript 2015也引入了该类型
示例函数可能如下所示:
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;
}
尽管您可能能够进行各种优化。typeof bar==='object'&&bar!==空
可能?这是一个错误。您正在询问在
中使用何时安全。你真正的问题是如何判断一个变量是否实际上是一个对象。不,我想知道我是否可以在
中使用。如果它不是一个对象,我可以在
中使用,很好。Duck test。因为“foo”不是字符串的实例。它是一个字符串原语,instanceof只对对象有效。此外,instanceof不会跨帧工作。为什么不直接使用typeof==“object”
?只是因为我不喜欢使用我还不懂的东西。像“字符串原语不是字符串”这样的语句让我犹豫不决。这是一种事后解决方案。我希望预测并避免错误的代码路径。(此外,它还将代码路径与其他异常混淆,我可能希望对此进行明确处理。)编辑代码以仅捕获由于foo-in-bar
导致的错误显然,正确的操作数是一个对象。请看我问题的底部。@spraff,这实际上也不是一个答案。您能澄清一下为什么这个测试可以工作,但我尝试的测试却不行吗?@spraff这很奇怪,因为OrdinaryHasInstance对于非对象返回false,所以您的foo instanceof Object
检查应该失败。您是否定义了自定义的@hasInstance方法?或者可能foo
是一个带有陷阱的代理,它会抛出?@spraff你为什么认为你尝试的那一个不会起作用?还有ES6符号。@Oriol,哦,是的,我引用了ES5规范。我已经更新了我的答案以记录它,但我必须去找一个ES6参考。@zzbov你的观点到底是什么?您可以将
中的运算符与functoid和正则表达式一起使用。此答案可能抛出(o=null
),产生误报(String.prototype.constructor=Object;o=”“
)或误报(o=[]
)。
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;
}