What is the meaning of || in javascript? - javascript

I am looking at these lines of code from here:
if (callback)
callback(sig || graph);
I have never see vertical "or" bars in a javascript method call. What do they mean? Do they pass the "true" parameter (i.e. sig or graph)? Do they pass the defined parameter? I have never seen that syntax before.

This is the logical OR operator in JS (and most other languages). It is defined in the spec at 11.11. As noted in the spec, expressions on either side will be evaluated first and the logical OR is left-to-right associative. Note that evaluation of the operands follows standard ToBoolean semantics from section 9.2, so [null, undefined, 0, ''] all count as falsy.
Unlike most languages, JS returns the left operand if it is truthy or the right operand otherwise. This behavior has been covered before in a number of SO questions, but is worth noting as most languages simply return true or false. This behavior is often used to provide default values to otherwise undefined variables.

The Logical OR operator (||) is an operator that returns its first or second operand depending on whether the first is truthy. A "truthy" value means anything other than 0, undefined, null, "", or false.
This operator uses short-circuiting, meaning if the first expression is truthy, then the second expression is not evaluated and the first operand is returned immediately. This is akin to the Logical AND operator (&&), which does the opposite: if the first operand is falsey, it returns it, otherwise it returns the second expression.

It means 'or' (http://www.w3schools.com/js/js_comparisons.asp) So if(sig OR graph)
BE CAREFUL you can 'short circuit' your code using this.
example :
If (foo || foo2)
if foo is true, then JavaScript wont even test foo2 at all, it just skips it.

It passes whichever evaluates as true, or sig if both are true.

The double pipe (||) represents OR in JS. In simple words, either this or that is True. It requires any of the sides true to get a True result.
For example:
var x = 8;
var y = 'c';
x >= 8 || y === 'a'
The left side of the double pipe returns True where the right side is False. Thus, the result is True.

The operator || means OR.
If either sig or graph are true or not null variables, callback function will receive a true argument.

Related

Javascript OR Expression: return Operand that is *not* NaN

I have an OR expression that should return the operand that is anything else than NaN:
(1 || NaN) // evaluates to 1
(NaN || 1) // evaluates to 1
But when the other operand is also a falsy value like 0, null, undefined or false, Javascript returns always the rightmost operand:
(0 || NaN) // evaluates to NaN
(NaN || 0) // evaluates to 0
// same for combinations of 0, null, undefined and false
Is there a way to fit the desired behaviour "Return the operand that is not NaN" into a nice & short expression or do I have to rely on an if/else construct?
You could add a default falsy value at the end of the expression, like
result = yourValue0 || yourValue1 || 0;
In this case, you get either a truthy value of yourValueX or the last falsy value.
Use an if-else-expression, also known as the conditional operator:
!isNaN(a) ? a : b
Try this:
var notNaN = [value1, value2, value3].find(item => !Number.isNaN(item))
This kind of operators use a lazy mechanism for their computation and this concept is called short circuting in javascript. Basically, JS returns value as soon as it feels no more computation is required to evaluate this expression. So, if its an && operator it will return as soon as it finds first non-truthy(0, "", null, undefined, NaN) as for && operator if any of the operands is non-truthy there is no point check rest of the operands as expression is already non-truthy, so it returns that value and exits, now if all the operands are truthy it checks till last and returns the last value. For || its just the opposite as soon as it finds first truthy value it returns otherwise keeps checking till last and returns it.

Using operators as variables gives odd results

! + [] === true
Can someone explain what's happening here? I understand this is not normal, but I'm struggling to understand what the compiler is doing when it seems operators used in place of variables in mathematical operations.
more examples of this strangeness:
(! + '') === (!'')
but
(! + []) !== (![])
JavaScript always convert inputs to Primitive types. So in your case of ! + [] it will try to convert +[] to string. which will be "" and then because of ! it will convert into boolean. in JavaScript "" is consider as false. So ultimately it will return !false which will be true.
Edit 1
As #mhodges has commented below. [] getting convert to string as "" then + will convert it to number, so it will become 0.
You can learn more about object to primitive from here.
object to primitive
You can check behavior below.
var emptyBrackets = [].toString();
// conversion to string.
console.log(emptyBrackets === '');
// conversion to number.
console.log(+emptyBrackets);
// conversion to boolean.
console.log(!0);
First, it is important to know what operators are being used, and in what order. When this is not clear, an easy way to find out is to look at what the syntax parser makes out of it, e.g. using https://astexplorer.net/, which shows for the first example that:
! + [] === true uses unary logical not (!), unary plus (+), an array literal which is empty ([]), strict equality (===) and the keyword for true (true).
Execution order is (!(+[])) === true, or seen as a tree:
===
/ \
! true
|
+
|
[]
What follows is to understand, what each of the operators are transforming their operands to. This is a bit tedious, when you want to know in detail.
I assume you know what an empty array literal or true produce. Strict equality === is likely also known, as it does not have very many unintuitive aspects (contrary to loose equality ==, which has a LOT). Relevant are therefore only the steps of the unary + and unary logical not.
Given the order of operations, we first look at unary + with [] as operand. It performs ToNumber on the operand, which, for objects like our example [], performs ToPrimitive followed by another ToNumber. ToPrimitive will try valueOf (which will not return a primitive and is therefore not taken), followed by toString. The latter, for arrays, searches for the function join and calls it without arguments (setting the array as this). For an empty array, this results in the empty string "", which will be converted to 0 by the following second call of ToNumber.
Next is the unary logical not, which first transforms any operand with ToBoolean. This intermediary step results in false for our operand 0. Then, as expected, the opposite is being returned (true).
Last but least, as we know, true === true evaluates to true.
An interesting sidenote here is the use of Array.prototype.join in the default case. I would expect many to be surprised, why changes to join would affect the outcome:
console.log(! + [] === true);
let x = [];
x.join = () => "1";
console.log(! + x === true);
Array.prototype.join = () => "1";
console.log(! + [] === true);
The other examples work in a similar way:
(! + '') is almost the same, just that ToNumber does not even need the prior ToPrimitive
For (!''), ToBoolean of an empty string is false, therefore resulting in true
For (![]), ToBoolean of any object is true, resulting in false

What is happening in this loose equality comparison of 2 empty arrays

I am struggling with understanding how this snippet works on a basic level
if([] == ![]){
console.log("this evaluates to true");
}
Please help me understand where I got it wrong. My thinking:
First there is operator precedence so ! evaluates before ==.
Next ToPrimitive is called and [] converts to empty string.
! operator notices that it needs to convert "" into boolean so it takes that value and makes it into false then negates into true.
== prefers to compare numbers so in my thinking true makes 1 and [] is converted into "" and then 0
Why does it work then? Where did I get it wrong?
Why does it work then?
TLDR:
[] == ![]
//toBoolean [1]
[] == !true
[] == false
//loose equality round one [2]
//toPrimitive([]); toNumber(false) [3]
"" == 0
//loose equality round two
//toNumber("") [4]
0 === 0
true
Some explanations:
1)
First there is operator precedence so ! evaluates before ==
Negating something calls the internal toBoolean method onto that "something" first. In this case this is an Object (as Arrays are Objects) and for that it always returns true which is then negated.
2)
Now it's up to loose equalities special behaviour ( see Taurus answer for more info) :
If A is an Object ( Arrays are Objects ) and B is a Boolean it will do:
ToPrimitive(A) == ToNumber(B)
3)
toPrimitive([])
ToPrimitive(A) attempts to convert its Object argument to a primitive value, by attempting to invoke varying sequences of A.toString and A.valueOf methods on A.
Converting an Array to its primitive is done by calling toString ( as they don't have a valueOf method) which is basically join(",").
toNumber(false)
The result is 1 if the argument is true. The result is +0 if the argument is false. Reference
So false is converted to +0
4)
toNumber("")
A StringNumericLiteral that is empty or contains only white space is converted to +0.
So finally "" is converted to +0
Where did I get it wrong?
At step 1. Negating something does not call toPrimitive but toBoolean ...
The accepted answer is not correct (it is now, though), see this example:
if([5] == true) {
console.log("hello");
}
If everything is indeed processed as the accepted answer states, then [5] == true should have evaluated to true as the array [5] will be converted to its string counterpart ("5"), and the string "5" is truthy (Boolean("5") === true is true), so true == true must be true.
But this is clearly not the case because the conditional does not evaluate to true.
So, what's actually happening is:
1. ![] will convert its operand to a boolean and then flip that boolean value, every object is truthy, so ![] is going to evaluate to false.
At this point, the comparison becomes [] == false
2. What gets into play then is these 2 rules, clearly stated in #6 in the specs for the Abstract Equality Comparison algorithm:
If Type(x) is boolean, return the result of the comparison ToNumber(x) == y.
If Type(y) is boolean, return the result of the comparison x == ToNumber(y)
At this point, the comparison becomes [] == 0.
3. Then, it is this rule:
If Type(x) is Object and Type(y) is either String or Number,
return the result of the comparison ToPrimitive(x) == y.
As #Jonas_W stated, an array's ToPrimitive will call its toString, which will return a comma-separated list of its contents (I am oversimplifying).
At this point, the comparison becomes "" == 0.
4. And finally (well, almost), this rule:
If Type(x) is String and Type(y) is Number,
return the result of the comparison ToNumber(x) == y.
An empty string converted to a number is 0 (Number("") == 0 is true).
At this point, the comparison becomes 0 == 0.
5. At last, this rule will apply:
If Type(x) is the same as Type(y), then
.........
If Type(x) is Number, then
.........
If x is the same Number value as y, return true.
And, this is why the comparison evaluates to true. You can also apply these rules to my first example to see why it doesn't evaluate to true.
All the rules I quoted above are clearly stated here in the specs.
First, realize that you are comparing two different types of values.
When you use ![] it results in false. You have code (at core it results in this):
if([] == false)
Now the second part: since both values are of different type and you are using "==", javascript converts both value type into string (to make sure that they have same type). It starts from left.
On the left we have []. So javascript applies the toString function on [], which results in false. Try console.log([].toString())
You should get false on the left as string value. On the right we have boolean value false, and javascript does the same thing with it.
It use the toString function on false as well, which results in string value false.
Try console.log(false.toString())
This involves two core concepts: how "==" works and associativity of "==" operator - whether it starts from left or right.
Associativity refers to what operator function gets called in: left-to-right or right-to-left.
Operators like == or ! or + are functions that use prefix notation!
The above if statement will result in false if you use "===".
I hope that helps.

Unexpected result from expression using &

Here if
document.write(eval("(2 == 2)"));
it prints true
And
document.write(eval("(2 == 2)&(5<10)"));
it prints 1
Why not it always returns true or false.If conditions increases in string it gives 0 or 1.What is the way to get same type of result.
Because & isn't a logical operator, it's a bitwise (numeric) operator. You probably meant &&, the logical AND operator.
Note that there's no reason for using eval in your code examples. (There's almost never any reason to use eval, there's almost always a better alternative — in this case, you don't even need an alternative.) Removing it would have exactly the same result.
It prints 1 because you used the bitwise and operator (&) instead of the logical and operator (&&).
And because JavaScript is loosely typed it will treat the boolean value true as an int value of 1, which you can check by invoking
document.write(eval("(2 == 2)+(5<10)"));
the result will be
2
& is a bitwise operator and returns a number. Try "(2 == 2)&&(5<10)"

What is the difference if("test") and if(!!"test")

What is the difference if("test") and if(!!"test"), only judged the false or true;
The question has a double negation expressson, that converts the type to boolean.
e.g.
var x = "test";
x === true; // evaluates to false
var x = !!"test";
x === true; //evalutes to true
!! will convert a "truthy" value in true, and a "falsy" value on false.
"Falsy" values are the following:
false
0 (zero)
"" (empty string)
null
undefined
NaN
If a variable x has any of these, then !!x will return false. Otherwise, !!x will return true.
On the practical side, there's no difference between doing if(x) and doing if(!!x), at least not in javascript: both will enter/exit the if in the same cases.
EDIT: See http://www.sitepoint.com/blogs/2009/07/01/javascript-truthy-falsy/ for more info
!! does type conversion to a boolean, where you are just dropping it in to an if, it is AFAIK, pointless.
There is no functional difference. As others point out,
!!"test"
converts to string to a boolean.
Think of it like this:
!(!("test"))
First, "test" is evaluated as a string. Then !"test" is evaluated. As ! is the negation operator, it converts your string to a boolean. In many scripting languages, non-empty strings are evaluated as true, so ! changes it to a false. Then !(!"test") is evaluated, changing false to true.
But !! is generally not necessary in the if condition as like I mention it already does the conversion for you before checking the boolean value. That is, both of these lines:
if ("test")
if (!!"test")
are functionally equivalent.

Categories