Why do these logical operators return an object and not a boolean?
var _ = (obj.fn && obj.fn() ) || obj._ || ( obj._ = {} );
var _ = obj && obj._;
I want to understand why it returns result of obj.fn()
(if it is defined) OR obj._
but not boolean result.
We can refer to the spec(11.11) of JS here of:
Semantics
The production LogicalANDExpression :LogicalANDExpression &&BitwiseORExpression is evaluated as follows:
2.Call GetValue(Result(1)).
3.Call ToBoolean(Result(2)).
4.If Result(3) is false, return Result(2).
5.Evaluate BitwiseORExpression.
6.Call GetValue(Result(5)).
7.Return Result(6).
see here for the spec
I think you have basic JavaScript methodology question here.
Now, JavaScript is a loosely typed language. As such, the way and manner in which it treats logical operations differs from that of other standard languages like Java and C++. JavaScript uses a concept known as "type coercion" to determine the value of a logical operation and always returns the value of the first
true
type. For instance, take a look at the code below:This is because
mystuff
is an a priori undefined entity which will always evaluate tofalse
when tested and as such, JavaScript skips this and tests the next entity for atrue
value. Since the document object is known to JavaScript, it returns atrue
value and JavaScript returns this object.If you wanted a boolean value returned to you, you would have to pass your logical condition statement to a function like so:
In JavaScript, both
||
and&&
are logical short-circuit operators that return the first fully-determined “logical value” when evaluated from left to right.In expression
X || Y
,X
is first evaluated, and interpreted as a boolean value. If this boolean value is “true”, then it is returned. AndY
is not evaluated. (Because it doesn’t matter whetherY
is true orY
is false,X || Y
has been fully determined.) That is the short-circuit part.If this boolean value is “false”, then we still don’t know if
X || Y
is true or false until we evaluateY
, and interpret it as a boolean value as well. So thenY
gets returned.And
&&
does the same, except it stops evaluating if the first argument is false.The first tricky part is that when an expression is evaluated as “true”, then the expression itself is returned. Which counts as "true" in logical expressions, but you can also use it. So this is why you are seeing actual values being returned.
The second tricky part is that when an expression is evaluated as “false”, then in JS 1.0 and 1.1 the system would return a boolean value of “false”; whereas in JS 1.2 on it returns the actual value of the expression.
In JS
false
,0
,-0
,""
,null
,undefined
,NaN
anddocument.all
all count as false.Here I am of course quoting logical values for discussion’s sake. Of course, the literal string
"false"
is not the same as the valuefalse
, and is therefore true.