问题
From a bug report, I think that the following expression might throw an exception if x is null:
if ( !x || doSomething( x[prop], y[prop] ) === false )
The exception is:
Cannot read property 'prop' of null
... as if the right side of the || is evaluated even if the left side is true. The javascript reference seems to indicate that that should not happen, but I'm not sure. I've tested that just writing x = null does not (always) crash, but is it guaranteed on every JS engine ?
EDIT:
Same question about
if( x && foo( x[prop] ) === true && bar() === false )
One way to put it is, does :
if( a && b && c )
... evaluates b or c if a === false ? The doc is not clear about that case, only for "a && ( expr1 && expr2 )", not "a && expr1 && expr2"
Full code snippet
var x = null;
var y = {
"p1": "p1",
"p2": "p2"
};
function f() {
return true;
}
for (var propName in y) {
if (x && f(y[propName]) === true && f(y[propName]) === false) {
doSomething(x[propName], y[propName]);
} else if (!x || f(x[propName], y[propName]) === false) {
console.log(y[propName]);
}
}
EDIT2: for completeness, the real (minimized) code that run in the browser
function a(c, b, e, f) {
for (var d in b) {
if (c && _.isObject(b[d]) === true && _.isArray(b[d]) === false) {
a(c[d], b[d], e, d + ".")
} else {
if (!c || _.isEqual(c[d], b[d]) === false) {
e.push({
name: f + d,
value: b[d]
})
}
}
}
return e
}
回答1:
"Is it guaranteed on every JS engine?"
We can't actually know that for sure, but the standard defines, how these operators should be implemented.
Logical OR:
- Let lref be the result of evaluating LogicalORExpression.
- Let lval be GetValue(lref).
- If ToBoolean(lval) is true, return lval.
- Let rref be the result of evaluating LogicalANDExpression.
- Return GetValue(rref).
http://es5.github.io/#x11.11
Item 3 doesn't leave any room to doubts, lval is returned immediately if lref can be evaluated to truthy, and rref will never be evaluated.
回答2:
The Javascript ||
operator is short-circuiting. The right-hand side will not evaluate if the left-hand side is true
. That's a fundamental property of the operator and should be equally implemented across all engines.
Therefore, the right-hand side will only evaluate if x
is truthy, and all truthy values in Javascript should be subscriptable without error.
Having said that, y
is completely unknown in this example and might throw an error.
回答3:
if (typeof y != 'undefined' && typeof x != 'undefined' && x !== null && y !== null) {
if (doSomething( x[prop], y[prop] ) === false) {
//do stuff
}
}
do the safety check before. this should be working
but note:
if your prop
Attribute does not exist, this will return an error too!
greetings
来源:https://stackoverflow.com/questions/34358276/is-that-js-expression-safe-if-x-dosomething-xprop-yprop-false