问题
I am reading the source code of Underscore.js, then something confused me:
// Its code, check the passed-in parameter obj
_.isObject = function(obj) {
var type = typeof obj;
return type === 'function' || type === 'object' && !!obj;
};
I am confused about the operator order of expression.
I think the operator precedence in
return type === 'function' || type === 'object' && !!obj;
will be from left to right; I mean equal to :
return (type === 'function' ) || ( type === 'object' && !!obj);
if type equal function return true; else operate type === 'object' && !!obj; if type equal object return !!obj ,same as Boolean(obj); else return false;
I made some examples:
var a = alert(1) || alert(2) && alert(3);
alert(a); //result : 1, 2 undefined;
var a = alert(1) || alert(2) && 0;
alert(a); //result : 1, 2 undefined;
what confused me:
Why
!!objshould exist? if we delete!!obj, code run as well.the operator order of this code? I know
&&operator are higher than||, so I guess!!objeffect when obj is null, but when I practice that is no what I want;
回答1:
They want to return false if the object is null. Usually when we need to know if something is an object, null is not what we're looking for. That's because trying to access null's properties (null[propName] for example) would throw an error.
console.log(typeof null);
The order of execution for the expression type === 'function' || type === 'object' && !!obj; is from left to right:
type === 'function' - if this istruethe expression will returntrue` without computing the resttype === 'object'- if this isfalsethe expression will returnfalsewithout computing the last part!!obj-nullwould returnfalse, any other object would returntrue
The snippet demonstrates the flow:
step(false, 1) || step(true, 2) && step(true, 3)
function step(ret, step) {
console.log(step);
return ret;
}
Using
!!we can cast values to booleans - So truthy values would be converted to true, for example!!{} === true, and falsy ones to false, for example!!null === false.
回答2:
The last
!!obj
forces the return value to a boolean value and yes, it is necessary because of typeof null is object.
回答3:
Firstly, the expression is not read left to right, && has a slightly higher precedence than ||, so it can be written either way -- a && b || c is identical to c || a && b. Operator precedence determines where parenthises should go in the expression, so a && b || c would be (a && b) || c. It's only within expressions where every operator has the same precedence that the operators are evaluated from left to right.
Regarding you're actual question -- in javascript, typeof null === "object", so the && !!obj part of the expression is to guard against null values evaluating to true.
来源:https://stackoverflow.com/questions/40928168/the-order-of-operators-in-javascript