Consider the following nested data structure:
var options = {
option1 = {
option1a : "foo",
option1b : "bar"
},
option2 = {},
}
I've got a data structure like the one above, which I'm using as a list of optional parameters for inputs to a function. Since all of this is optional inputs, it may or may not exist. Initially, I was using chains of typeof x == "undefined"
statements to make sure that, for example, options
, option1
, and option1a
are all defined. My code would end up looking like this for defining a variable:
if(typeof option != "undefined"
&& typeof option.option1 != "undefined"
&& typeof option.option1.option1a != "undefined){
var x = option.option1.option1a;
} else {
var x = "default";
};
I noticed that I can shorten this to the following:
var x = option && option.option1 && option.option1.option1a || "default";
Does &&
consistently return the last true or first false statement? And does ||
consistently return the first true statement? Logic would dictate that they could return booleans in some implementations, but I don't know enough about browser / javascript implementations to make that statement definitively. Is this a safe way to go about doing this, or is there a better way?
Yes that will work correctly. &&
returns the last true statement or first false statement, ||
returns the first true statement or last false statement.
var a = false || 0 // a === 0
var b = false && 0 // b === false
var c = true || 1 // c === true
var d = true && 1 // d === 1
and &&
is evaluated before ||
so
var e = false || 0 && null // e === null
var f = 1 || 2 && 3 // f === 1
Its also worth mentioning that falsy values encompass more than undefined in JS, so your 2 checks are not quite the same. A value of 0 for instance, will be considered falsy, even if it is "defined"
See the official spec here for the detailed logical specification.
Syntax
LogicalANDExpression : BitwiseORExpression LogicalANDExpression && BitwiseORExpression LogicalANDExpressionNoIn : BitwiseORExpressionNoIn LogicalANDExpressionNoIn && BitwiseORExpressionNoIn LogicalORExpression : LogicalANDExpression LogicalORExpression || LogicalANDExpression LogicalORExpressionNoIn : LogicalANDExpressionNoIn LogicalORExpressionNoIn || LogicalANDExpressionNoIn
Semantics
The production LogicalANDExpression : LogicalANDExpression && BitwiseORExpression is evaluated as follows: Let lref be the result of evaluating LogicalANDExpression. Let lval be GetValue(lref). If ToBoolean(lval) is false, return lval. Let rref be the result of evaluating BitwiseORExpression. Return GetValue(rref). The production LogicalORExpression : LogicalORExpression || LogicalANDExpression is evaluated as follows: Let lref be the result of evaluating LogicalORExpression. Let lval be GetValue(lref). If ToBoolean(lval) is true, return lval. Let rref be the result of evaluating LogicalANDExpression. Return GetValue(rref). The LogicalANDExpressionNoIn and LogicalORExpressionNoIn productions are evaluated in the same manner as the LogicalANDExpression and LogicalORExpression productions except that the contained LogicalANDExpressionNoIn, BitwiseORExpressionNoIn and LogicalORExpressionNoIn are evaluated instead of the contained LogicalANDExpression, BitwiseORExpression and LogicalORExpression, respectively. **NOTE** The value produced by a && or || operator is not necessarily of type Boolean. The value produced will always be the value of one of the two operand expressions.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With