As far as I know, The logical && works like the following
var test = false;
var foo = test && 42;
This code, will assign 42 to foo only if the first condition gets evaluated to true. So in this example, foo will keep its current value.
I'm wondering why this snippet doesn't work at all:
var test = "";
var foo = test && 42;
Now, foo gets the value from test assigned. I'm very confused. The empty string is one of Javascripts falsy values, so why would the && operator fail in this scenario ?
Can someone help me out with the spec on this one please ?
You're misunderstanding the operator.
foo = x && y will always assign foo.
The && operator evaluates to its left-most "falsy" operand.
false && 42 evaluates to false; "" && 42 evaluates to "".
var foo = test && 42; assigns false to foo.
You have answered your question yourself.
var foo = test && 42;
42 will be assigned to foo only if test evaluated to true.
So if test is empty string (evaluated to false), 42 won't assigned to foo, foo will be the empty string.
Related
So the double pipe || is the logical OR operator.
I want to create a function where it can be either foo, or when thats flase (or falsy?) then it should use a default fallback. In this case 'bar'.
const foo = 0;
const bar = 'somethingElse';
const qux = foo || bar;
console.log(qux); // returns 'somethingElse'
Now the above example will work unless foo is 0. Since JS will interpret that als falsy.
Now the following seems to be working:
// ...
const qux = typeof foo !== 'undefined' ? foo : bar;
But I'm wondering if there is a better solution. What would be the best way of handling such a scenario?
Yes, || checks for the first operand to be falsy (false when coerced to a boolean), and 0 is exactly that.
If you want to check for null and undefined only, you can use the nullish-coalescing operator:
const qux = foo ?? bar;
If you want to check for exactly undefined, you should use the conditional operator as you did.
Since the issue is only if foo is 0.
So you can modify the condition like this. This will work for everything as expected.
const qux3 = ((foo === 0 && foo) || foo) || bar;
The following coffeescript code
if a isnt undefined
b = 1
if a?
b = 1
compiles to the following javascript
var b;
if (a !== void 0) {
b = 1;
}
if (typeof a !== "undefined" && a !== null) {
b = 1;
}
Are the two checks equivalent? Under what conditions do they differ?
TLDR: In general, when checking for presence of a variable, foo? will be the safest.
foo? checks that foo is neither null nor undefined. It will not throw an error if the foo has not been declared:
typeof foo !== "undefined" && foo !== null;
> false
var foo = null;
typeof foo !== "undefined" && foo !== null;
> false
var foo = 123;
typeof foo !== "undefined" && foo !== null;
> true
foo isnt undefined checks that foo is not equal to undefined. If foo has not been declared it will throw an error. If foo is null it will return true:
foo !== void 0;
> ReferenceError // OH NO!
var foo;
foo !== void 0;
> false
var foo = 123;
foo !== void 0;
> true
var foo = null;
foo !== void 0;
> true // OH NO!
NOTE: void 0 is equivalent to undefined
In JavaScript, the void operator evaluates the expression and then returns undefined. So void 0 returns undefined. Therefore isnt undefined strictly tests against undefined whereas ? checks against undefined and null.
The two would differ in any case that the value being checked was null rather than undefined as the type values are distinctly different.
From the Coffeescript website:
CoffeeScript's existential operator ? returns true unless a variable is null or undefined.
isnt, on the other hand, just translates to !==, which means it is an unequal comparison without type conversion.
So, taken together, the first check in your example would return true if and only if a is not undefined. The second one would return true if a is not undefined and not null.
a isnt undefined
evaluates to false if a is undefined, true otherwise
a?
evaluates to false if a is undefined or null, true otherwise
So the only functional difference is whether null is true or false.
In terms of readability the first one will be clear to pretty much anyone, the second is shorter and is clear to anyone who has a basic knowledge of coffeescript syntax.
I've often used the following pattern in my Javascript:
x = couldBeNullThing || valueIfItIsNull;
because it beats than:
x = couldBeNullThing ? couldBeNullThing : valueIfItIsNull;
I also frequently use a slight variant of that same pattern:
x = x || valueIfXIsNotDefined;
That's all great ... except the problem is, I recently discovered:
foo = "";
//assert foo.x === undefined;
foo.x = foo.x || valueIfXIsNotDefined;
//assert foo.x === undefined;
In other words, if you have a string, and you do string.aPropertyThatStringDoesntHave || foo, you'll get back neither foo nor an actual value; instead you get undefined.
Can anyone explain why this is? It seems to me that if foo.x is undefined, then foo.x || anythingElse should always result in anythingElse ... so why doesn't it?
While I'm familiar with the concept of assert I wasn't aware that JavaScript had that functionality. So with that in mind I could be completely wrong but it seems to me that this statement:
assert (foo.x || valueIfXIsNotDefined) === undefined;
...is calling a function called assert(), passing it the parameter foo.x || valueIfXIsNotDefined and then comparing the return value from the assert() function with undefined. Perhaps what you need is this:
assert(foo.x || valueIfXIsNotDefined === undefined);
If I try something similar with console.log():
var foo = "",
valueIfXIsNotDefined = "test";
console.log( foo.x === undefined);
console.log(foo.x || valueIfXIsNotDefined === undefined);
Then it logs:
true
false
Similarly, after:
var result = foo.x || valueIfXIsNotDefined;
result is "test".
http://jsfiddle.net/YBPyw/
Further, if you actually try to assign foo.x equal to something (where foo was a string) it doesn't work, so when you later test foo.x it will give undefined.
Why would you use this syntax?
var myVar = myArray.length && myArray || myObject;
instead of
var myVar = myArray.length ? myArray : myObject;
Edit: I just had a thought that if in the case of the && || syntax both sides of the || evaluated to false, as you might expect if myObject was undefined or null, if false would be returned. But it isn't, the objects value undefined or null is returned.
true || true //true
true || false //true
false || true //true
false || false //false
Edit2:
!!(myArray.length ? myArray : myObject);
This does however return false if myObject is undefined or null
x && y || z is different than x ? y : z even if it "works" in the case presented.
Consider when y evaluates to a false-value (in the post y can't be a false-value when it is evaluated because it is dependent upon x and thus it "works" as expected).
Using ?: is the much better and more clear construct in this case. The only reason I can give for using the other syntax is "too much cleverness".
A ternary is the only correct thing to do here, unless you guarantee that myObject.name has a "true" value.
Consider
res = a ? b : c;
vs.
res = a && b || c;
What is the difference? The first does what it is supposed to. But the second tests a. If a is false, it gets c, as the ternary version.
But if a is true, it only gets b if this is true as well, if not, it gets c, what is not wanted at all.
Tastes vary. Maybe somebody just got in the habit of writing things like
var myName = myObject && myObject.name || "unknown";
and stuck with it even when a ternary would work as well.
http://jsperf.com/conditional-operators
It looks like you use && || when you want your code to go slower and you want to obfuscate it a little more :)
There's also a difference between what is going on.
foo && bar || foobar // if foo or bar is false, then foobar will be returned
foo?bar:foobar // the bar, or foobar, is decided solely on foo
If you wanted the ternary to act like the logical conditional it would be:
foo&&bar?bar:foobar
This question already has answers here:
What does the construct x = x || y mean?
(12 answers)
Closed 7 years ago.
I came over a snippet of code the other day that I got curious about, but I'm not really sure what it actually does;
options = options || {};
My thought so far; sets variable options to value options if exists, if not, set to empty object.
Yes/no?
This is useful to setting default values to function arguments, e.g.:
function test (options) {
options = options || {};
}
If you call test without arguments, options will be initialized with an empty object.
The Logical OR || operator will return its second operand if the first one is falsy.
Falsy values are: 0, null, undefined, the empty string (""), NaN, and of course false.
ES6 UPDATE: Now, we have real default parameter values in the language since ES6.
function test (options = {}) {
//...
}
If you call the function with no arguments, or if it's called explicitly with the value undefined, the options argument will take the default value. Unlike the || operator example, other falsy values will not cause the use of the default value.
It's the default-pattern..
What you have in your snippet is the most common way to implement the default-pattern, it will return the value of the first operand that yields a true value when converted to boolean.
var some_data = undefined;
var some_obj_1 = undefined;
var some_obj_2 = {foo: 123};
var str = some_data || "default";
var obj = some_obj1 || some_obj2 || {};
/* str == "default", obj == {foo: 123} */
the above is basically equivalent to doing the following more verbose alternative
var str = undefined;
var obj = undefined;
if (some_data) str = some_data;
else str = "default";
if (some_obj1) obj = some_obj1;
else if (some_obj2) obj = some_obj2;
else obj = {};
examples of values yield by the logical OR operator:
1 || 3 -> 1
0 || 3 -> 3
undefined || 3 -> 3
NaN || 3 -> 3
"" || "default" -> "default"
undefined || undefined -> undefined
false || true -> true
true || false -> true
null || "test" -> "test"
undefined || {} -> {}
{} || true -> {}
null || false || {} -> {}
0 || "!!" || 9 -> "!!"
As you can see, if no match is found the value of the last operand is yield.
When is this useful?
There are several cases, though the most popular one is to set the default value of function arguments, as in the below:
function do_something (some_value) {
some_value = some_value || "hello world";
console.log ("saying: " + some_value);
}
...
do_something ("how ya doin'?");
do_something ();
saying: how ya doin'?
saying: hello world
Notes
This is notably one of the differences that javascript have compared to many other popular programming languages.
The operator || doesn't implicitly yield a boolean value but it keeps the operand types and yield the first one that will evaluate to true in a boolean expression.
Many programmers coming from languages where this isn't the case (C, C++, PHP, Python, etc, etc) find this rather confusing at first, and of course there is always the opposite; people coming from javascript (perl, etc) wonders why this feature isn't implemented elsewhere.
Yes. The sample is equivalent to this:
if (options) {
options = options;
} else {
options = {};
}
The OR operator (||) will short-circuit and return the first truthy value.
Yes, that's exactly what it does.
Found another variation of this:
options || (options = {});
Seems to do the same trick.