Pierre
Pierre

Reputation: 19071

return String vs Integer vs undefined vs null

Why does javascript prefers to return a String over any other choices ?

Consider the following snippet.

var arr = ['Hello1', 'Hello2', 'Hello3'];

Array.prototype.item = function(x) {
   return this[x] || null || 'aïe' || 12 || undefined ;
};

console.log( arr.item(43) ); // returns aïe

I intentionally called a non-existent array element.

However i cannot understand why does arr.item(43) returns the String ? Why not null or undefined or even 12 ?

Upvotes: 8

Views: 3013

Answers (6)

user1106925
user1106925

Reputation:

Because this[x] is undefined, which is falsy, and so is null.

The || operator returns the first "truthy" value it finds, and stops its evaluation at that point.

If no "truthy" value is found, it returns the result of the last operand evaluated.

There are a total of 6 "falsey" values. They are...

  1. false
  2. undefined
  3. null
  4. ""
  5. NaN
  6. 0

Everything else is considered truthy.

So your expression will be evaluated as...

//   v--falsey            v--truthy! return it!
((((this[x] || null) || 'aïe') || 12) || undefined);
//               ^--falsey         ^--------^---these are not evaluated at all

Or you could look at it like this:

(
  (
    (
      (this[x] || null) // return null
            /* (null */ || 'aïe') // return 'aïe' and stop evaluating
                                || 12) 
                                      || undefined);

Upvotes: 25

Mark Byers
Mark Byers

Reputation: 838076

The code a || b is roughly equivalent to a ? a : b, or this slightly more verbose code:

if (a) {
    result = a;
} else {
    result = b;
}

Since || is left-associative the expression a || b || c is evaluated as (a || b) || c.


So in simple terms this means that the || operator when chained returns the first operand that is "truthy", or else the last element.

This feature can be useful for providing defaults when you have missing values:

var result = f() || g() || defaultValue;

You could read this as: Get the result of f(). If it's a falsey value, then try g(). If that also gives a falsey value, then use defaultValue.

Upvotes: 3

techfoobar
techfoobar

Reputation: 66663

return this[x] || null || 'aïe' || 12 || undefined will not return one of those. It is supposed to return the result of the expression this[x] || null || 'aïe' || 12 || undefined - I believe it will return a boolean value.

Upvotes: 0

Ernest Friedman-Hill
Ernest Friedman-Hill

Reputation: 81684

The statement

return this[x] || null || 'aïe' || 12 || undefined ;

will evaluate the subexpressions left to right, and will return the first subexpression that does not evaluate to false. The non-existent element evaluates to false as it's undefined, and null is false by definition. That leaves the string as the first non-false subexpression, so that's what you get.

Upvotes: 5

John Hartsock
John Hartsock

Reputation: 86872

Because it is evaluating in order from left to right.

If you were to modify to this:

return this[x] || null || 12 || 'aïe' || undefined ;

Your answer would be 12.

Upvotes: 1

Jamiec
Jamiec

Reputation: 136094

The string is the first truthy value in the chain of or's. Simples.

Upvotes: 1

Related Questions