This statement
if ('foo' in bar)
throws a TypeError if bar
is a string. I presume it's possible to have the same error for other types of object.
How can I tell if bar
is an object which supports the in
operator?
This code isn't sufficient: if foo
is a string, it passes through to the in
statement and throws.
if (foo instanceof Object && ! (foo instanceof String))
{
if ('foo' in foo) {}
}
The in
operator throws a TypeError is the right operand is not an object.
You can check if a value is an object using
Object(value) === value;
Additionally, in
operator calls internal [[HasProperty]] method. For ordinary objects it should never throw , but it might be the case in some exotic objects. For example,
var proxy = new Proxy({}, {has: () => {throw "Can't use `in`"}});
"property" in proxy; // Error: Can't use `in`
To handle these cases, I think you can only use a try
statement, as ringø suggested .
var o = {};
console.log(o.constructor === Object && o !== null); //true
To catch any error
try {
if ('foo' in bar) {
}
}
catch(e) {
// 'foo' is not in bar
}
or if you want just to catch errors for 'foo' in bar
var inbar = false;
try { if ('foo' in bar) inbar = true; }
catch(e) {}
if (inbar) {
...
}
How can I detect whether it is safe to use
in
operator in Javascript?
The production RelationalExpression : RelationalExpression in ShiftExpression is evaluated as follows:
- Let lref be the result of evaluating RelationalExpression.
- Let lval be GetValue(lref).
- Let rref be the result of evaluating ShiftExpression.
- Let rval be GetValue(rref).
- If Type(rval) is not Object, throw a TypeError exception.
- Return the result of calling the [[HasProperty]] internal method of rval with argument ToString(lval).
Emphasis mine.
In ES5 Type()
can be
So to prevent TypeError
s from happening, you have to make sure that it's not
undefined
null
true
or false
EcmaScript 2015 introduces the Symbol
type as well.
An example function might look like:
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;
}
Although you may be able to make various optimizations.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.