问题
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
!!obj
should exist? if we delete!!obj
, code run as well.the operator order of this code? I know
&&
operator are higher than||
, so I guess!!obj
effect 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 is
truethe expression will return
true` without computing the resttype === 'object'
- if this isfalse
the expression will returnfalse
without computing the last part!!obj
-null
would 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