Why don't logical operators (&& and ||) always

2018-12-31 14:53发布

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.

9条回答
若你有天会懂
2楼-- · 2018-12-31 15:25
var _ = ((obj.fn && obj.fn() ) || obj._ || ( obj._ == {/* something */}))? true: false 

will return boolean.

UPDATE

Note that this is based on my testing. I am not to be fully relied upon.

It is an expression that does not assign true or false value. Rather it assigns the calculated value.

Let's have a look at this expression.

An example expression:

var a = 1 || 2;
// a = 1

// it's because a will take the value (which is not null) from left
var a = 0 || 2;
// so for this a=2; //its because the closest is 2 (which is not null)

var a = 0 || 2 || 1;    //here also a = 2;

Your expression:

var _ = (obj.fn && obj.fn() ) || obj._ || ( obj._ = {} );

// _ = closest of the expression which is not null
// in your case it must be (obj.fn && obj.fn())
// so you are gettig this

Another expression:

var a = 1 && 2;
// a = 2

var a = 1 && 2 && 3;
// a = 3 //for && operator it will take the fartest value
// as long as every expression is true

var a = 0 && 2 && 3;
// a = 0

Another expression:

var _ = obj && obj._;

// _ = obj._
查看更多
梦醉为红颜
3楼-- · 2018-12-31 15:26

In most programming languages, the && and || operators returns boolean. In JavaScript it's different.


OR Operator:

It returns the value of the first operand that validates as true (if any), otherwise it returns the value of the last operand (even if it validates as false).

Example 1:

var a = 0 || 1 || 2 || 3;
        ^    ^    ^    ^
        f    t    t    t
             ^
             first operand that validates as true
             so, a = 1

Example 2:

var a = 0 || false || null || '';
        ^    ^        ^       ^
        f    f        f       f
                              ^
                              no operand validates as true,
                              so, a = ''

AND Operator:

It returns the value of the last operand that validates as true (if all conditions validates as true), otherwise it returns the value of the first operand that validates as false.

Example 1:

var a = 1 && 2 && 3 && 4;
        ^    ^    ^    ^
        t    t    t    t
                       ^
                       last operand that validates as true
                       so, a = 4

Example 2:

var a = 2 && '' && 3 && null;
        ^    ^     ^    ^
        t    f     t    f
             ^
             entire condition is false, so return first operand that validates as false,
             so, a = ''

Conclusion:

If you want JavaScript to act the same way how other programming languages work, use Boolean() function, like this:

var a = Boolean(1 || 2 || 3);// a = true
查看更多
人间绝色
4楼-- · 2018-12-31 15:27

Compare:

var prop;
if (obj.value) {prop=obj.value;}
else prop=0;

with:

var prop=obj.value||0;

Returning a truthy expression - rather than just true or false - usually makes your code shorter and still readable. This is very common for ||, not so much for &&.

查看更多
梦该遗忘
5楼-- · 2018-12-31 15:30

In the simplest terms:

The || operator returns the first truthy value, and if none are truthy, it returns the last value (which is a falsy value).

The && operator returns the first falsy value, and if none are falsy, it return the last value (which is a truthy value).

It's really that simple. Experiment in your console to see for yourself.

"" && "Dog"    // ""
"Cat" && "Dog" // "Dog"
"" || "Dog"    // "Dog"
"Cat" || "Dog" // "Cat"

查看更多
浅入江南
6楼-- · 2018-12-31 15:30

You could use !! before the condition to get the Boolean result.

!!(X && Y) // returns true if both X and Y are not null or undefined
查看更多
十年一品温如言
7楼-- · 2018-12-31 15:31

First, it has to be true to return, so if you are testing for truthfulness then it makes no difference

Second, it lets you do assignments along the lines of:

function bar(foo) {
    foo = foo || "default value";
查看更多
登录 后发表回答