Logical OR (||) in JavaScript - javascript

A book states following rules for OR:
If the first operand is an object, then the first operand is returned.
If the first operand evaluates to false, then the second operand is returned.
If both operands are objects, then the first operand is returned.
If both operands are null, then null is returned.
If both operands are NaN, then NaN is returned.
If both operands are undefined, then undefined is returned.
However I observed following behavior while coding:
var result18 = (NaNVar || undefinedVar); //undefined
var result19 = (NaNVar || nullVar); //null
var result20 = (undefinedVar || NaNVar); //NaN
var result21 = (undefinedVar || nullVar); //null
var result22 = (nullVar || NaNVar); //NaN
var result23 = (nullVar || undefined); //undefined
How can I justify this behavior for those rules?

This rule is the key:
If the first operand evaluates to false, then the second operand is
returned.
All of your left hand side values evaluate to false, so the right hand side is returned.
Here's a good definition from MDN if it helps you:
expr1 || expr2
Returns expr1 if it can be converted to true; otherwise, returns
expr2. Thus, when used with Boolean values, || returns true if either
operand is true; if both are false, returns false.
https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/Logical_Operators

Sorry for the confusion around the description in the book. I was trying to enumerate edge cases and I see how that could cause some confusion.
You can accurately describe the operation using only two rules: if the first argument is truthy then return the first argument; if the first argument is falsy return the second argument. Your third rule doesn't just apply to this operator, an undeclared variable will always causing her to be thrown when you try to use it. It doesn't matter what you try to use it for (with the exception of typeof and delete, which work fine in undeclared variables).

Your book has chosen a terrible way to describe the logical OR operator.
For example, this rule is far too limiting.
If the first operand is an object, then the first operand is returned.
The operator does not do any sort of type check. It doesn't care if the first or second operand is an "object". It only cares about how they coerce to a boolean.
Take this example.
"foobar" || false
The first operand is a string, not an object, but it will coerce to the boolean true, so the first operand is returned.
Boolean("foobar"); // true
Your book is walking through bullet points as though it was following some sort of specified algorithm. There is no such algorithm. The comparison is strictly based on Boolean coercion.
To put it simply,
it evaluates operands from left to right until one is found that will coerce to true or until it runs out of operands.
the last operand evaluated is returned (uncoerced)
11.11 Binary Logical Operators
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).

Yes after observing the results, I concluded two simple rules:
//1: if the first operand evaluates to true then it is returned (here it means actual //value of operand is returned but not the evaluated value that is true)
//following values evaluates to ture: non-empty string, non-zero number and //none of these values- NaN, null, undefined
var result = ("Mahesh" || false) //"Mahesh"
var result = ("Mahesh" || true) //"Mahesh"
var result = ("Mahesh" || undefined) //"Mahesh"
var result = ("Mahesh" || null) //"Mahesh"
var result = ("Mahesh" || NaN) //"Mahesh"
var result = (5 || false) //5
var result = (5 || true) //5
var result = (5 || null) //5
var result = (5 || NaN) //5
var result = (5 || undefined) //5
//2: if first operand evaluates to false then the value of second operand is //returned, again without evaluating it
//following values evaluate to false: empty string (""), number zero (0), null, //NaN, undefined or false)
var result = (false || NaN); //NaN
var result = (false || null); //null
var result = (false || undefined); //undefined
var result = (false || "Mahesh"); //Mahesh
var result = (false || 5); //5
var result = (NaN || false); //false
var result = (NaN || true); //true
var result = (NaN || NaN); //NaN
var result = (NaN || null); //null
var result = (NaN || undefined); //undefined
var result = (NaN || "Mahesh"); //Mahesh
var result = (NaN || 5); //5
var result = (null || false); //false
var result = (null || true); //true
var result = (null || NaN); //NaN
var result = (null || null); //null
var result = (null || undefined); //undefined
var result = (null || "Mahesh"); //Mahesh
var result = (null || 5); //5
var result = (undefined || false); //false
var result = (undefined || true); //true
var result = (undefined || NaN); //NaN
var result = (undefined || null); //null
var result = (undefined || undefined); //undefined
var result = (undefined || "Mahesh"); //Mahesh
var result = (undefined || 5); //5
var result = (0 || false); //false
var result = (0 || true); //true
var result = (0 || NaN); //NaN
var result = (0 || null); //null
var result = (0 || undefined); //undefined
var result = (0 || "Mahesh"); //Mahesh
var result = (0 || 5); //5
var result = ("" || false); //false
var result = ("" || true); //true
var result = ("" || NaN); //NaN
var result = (""|| null); //null
var result = (""|| undefined); //undefined
var result = ("" || "Mahesh"); //Mahesh
var result = ("" || 5); //5
//Note: if the first operand evaluates to false and if the second operand is undeclared
//variable then it will cause an error
var result = (false || undeclaredVar); //error
I think that's all in it in simpler words. Can anyone here confirm if I have got right understanding?
I tried this in IE10, hope things will be consistent across other browsers.

Related

Operator precedence for logical AND (&& )and logical OR (||)

As per the operator precedence table for JavaScript, I can see that && has higher precedence than ||.
So, for the following code snippet:
let x, y;
let z = 5 || (x = false) && (y = true);
console.log(z); // 5
console.log(x); // undefined
console.log(y); // undefined
I thought that && should be evaluated first and after short-circuiting for the && part, x would be assigned the value false. And then only, || would be tried to be evaluated.
But, from the output of the console.log, I can clearly see that's not the case here.
Can someone please help me what am I missing here?
Thanks in advance.
What the operator precedence of && of || means is that this:
let z = 5 || (x = false) && (y = true);
gets evaluated as:
let z = 5 || ((x = false) && (y = true));
and not as
let z = (5 || (x = false)) && (y = true);
It's not something that indicates when the values on each side of an operator is evaluated. That's done by the mechanics of each individual operator. For example, for ||, it's specified here:
1. Let lref be the result of evaluating LogicalANDExpression.
2. Let lval be ? GetValue(lref).
3. Let lbool be ToBoolean(lval).
4. If lbool is false, return lval.
5. Let rref be the result of evaluating BitwiseORExpression.
6. Return ? GetValue(rref).
It evaluates GetValue(lref) before GetValue(rref) runs.
In other words, operator precedence indicates which tokens are applied to which operator, and in what order, but not how/when a given operator evaluates the values on its left and right side.

make a insert function for bracket.js

I'm a making function that replace null by another word/value.
the var in question :
var saveData = {"teams":[[null,null],[null,null]]}
I find out that the variable is a 2D array and to acces a null I shoud do savedata.teams[0][0] so i made a script that modify the variable.
function add(team, data)
{
var str = team.innerHTML;
var str = str.replace(/<td>/g, "");
var text = str.split("</td>");
var i = 0;
while(data.teams[i][0] != null || data.teams[i][1] != null)
{
i++;
}
if( i == data.teams.length - 1){}
if(data.teams[i][0] == null)
{
data.teams[i][0] = text[1];
}
else if(data.teams[i][0] != null)
{
data.teams[i][1] == text[1];
}
$(function() {
var container = $('.creator')
container.bracket({
init: data,
save: saveFn,
userData: ""})
})
}
the result is wierd. it output :
first use :
{"teams":[["team 1",null],[null,null]]}
seconde use :
{"teams":[["team 1",null],["team 2",null]]}
I don't know why, but I suspect the error may come from the while or the if
data.teams[i][0] != null || data.teams[i][1] != null if any of the two value is not null... it move to next element....
its supposed to be:
while(i < data.teams.length)
{
i++;
}
if(data.teams[i][0] == null)
{
data.teams[i][0] = text[1];
}
if(data.teams[i][0] != null)
{
data.teams[i][1] == text[1];
}
Check more into logical operators here.
Logical AND (&&)
Returns expr1 if it can be converted to false; otherwise, returns
expr2. Thus, when used with Boolean values, && returns true if both
operands are true; otherwise, returns false.
Logical OR (||)
Returns expr1 if it can be converted to true; otherwise, returns
expr2. Thus, when used with Boolean values, || returns true if either
operand is true.

Removing numeric values from alphanumeric string

I want to remove all numeric values from a string
But only if the string contains at least one letter.
How can I do this in JavaScript?
For e.g.
var s = "asd23asd"
Then result must be asdasd
However if
var s = "123123"
Then result must be 123123 as the string does not have any letters.
function filter(string){
var result = string.replace(/\d/g,'')
return result || string;
}
or directly
var newString = string.replace(/\d/g,'') || string;
Why || works
the || and & are conditionals operators and sure that you used in if, while ...
If you do somethin like
var c1 = false, c2 = true, c3= false, c4 = true;
if( c1 || c2 || c3 || c4) {
}
This evaluation will stop in the first moment that is valid or invalid.
this mind that the evaluation stop in c2 this mind that is more fast
(true || false) than (false || true)
At this point we can add another concept, the operator return always the last element in the evaluation
(false || 'hey' || true) return 'hey', remember in JS 'hey' is true but '' is false
Interesting examples:
var example = {
'value' : {
'sub_value' : 4
}
}
var test = example && example.value && example.value.sub_value;
console.log(test) //4
var test_2 = example && example.no_exist && example.no_exist.sub_value;
console.log(test_2) //undefined
var test_3 = example.valno_existue.sub_value; //exception
function test_function(value){
value = value || 4; //you can expecify default values
}
You can try this. First check if the word contains any alphabet, if yes then replace.
var s = "asd23asd";
if(/\w+/.test(s))
s = s.replace(/\d+/g, '');
([a-zA-Z]+)\d+|\d+(?=[a-zA-Z]+)
You can try this.Replace by $1.See demo.
https://regex101.com/r/nS2lT4/27
Javascript Code
var txt='asd23ASd3';
if(parseInt(txt))
var parsed=txt;
else
var parsed=txt.replace ( /[^a-zA-Z]/g, '');
console.log(parsed)

optional arguments and default value

I am new to javascript does the following 2 functions does the same thing and would you pick one over another?
var multiply = function(arg1, arg2) {
arg1 && (arg1 = 0);
arg2 && (arg2 = 0);
return arg1*arg2;
}
var multiply = function(arg1, arg2) {
arg1 = arg1 || 0;
arg2 = arg2 || 0;
return arg1*arg2;
}
the reason i am asking is i saw something like this for the first time
function(path, limit) {
var ref = firebaseRef(path);
limit && (ref = ref.limit(limit)); //if i understood correctly this line does an assignment based on condition without an if statement
return $firebase(ref);
}
function(path, limit) {
var ref = firebaseRef(path);
limit && (ref = ref.limit(limit)); // Important
return $firebase(ref);
}
The Important line, can be written like this
if (limit) {
ref = ref.limit(limit);
}
But if you wanted to write it like the first way, you would have done,
ref = limit && ref.limit(limit)
This has one problem, when limit is Falsy && immediately returns the evaluated Falsy value of limit, so ref is Falsy now. You wouldn't have wanted this, I believe.
At the end of the day, as a programmer, readability and maintainability of the code of the code what we write matters. So, I would recommend using an explicit if check, which I mentioned at the beginning of the answer.
Note: Also, as noted by others, the first multiply should have been like this
var multiply = function(arg1, arg2) {
arg1 || (arg1 = 0);
arg2 || (arg2 = 0);
return arg1 * arg2;
}
Even better, I would have written it like this
var multiply = function(arg1, arg2) {
return (arg1 || 0) * (arg2 || 0);
}
Both are variable assignments which evaluate differently on the logical operation.
For example expr1 && expr2 will return expr1 if expr1 returns false otherwise the variable assignment will evaluate to the second expression (i.e. expr2).
Using the logical-or operation will return expr1 if it evaluates to true, otherwise it will return expr2.
Consider the following:
// Logical AND
var a1 = true && true; // t && t returns true
var a2 = true && false; // t && f returns false
var a3 = false && true; // f && t returns false
var a4 = false && (3 == 4); // f && f returns false
var a5 = "Cat" && "Dog"; // t && t returns Dog
var a6 = false && "Cat"; // f && t returns false
var a7 = "Cat" && false; // t && f returns false
// Logical OR
var o1 = true || true; // t || t returns true
var o2 = false || true; // f || t returns true
var o3 = true || false; // t || f returns true
var o4 = false || (3 == 4); // f || f returns false
var o5 = "Cat" || "Dog"; // t || t returns Cat
var o6 = false || "Cat"; // f || t returns Cat
var o7 = "Cat" || false; // t || f returns Cat
For more information, see: Mozilla Developer Network on Logical Operator Expressions
I think the first one will actually do the opposite of what you want. Let's test this with a few cases:
arg1 && (arg1 = 0);
If arg1 is 0, or any other falsy value, so the execution goes as follows:
0 (meaning false) AND an assignment. The expression will immediately return false without executing the arg1 = 0 statement, because false || (t/f) always returns false.
If arg1 is 1, or any other truthy value, so we have:
1 (meaning true) AND an assignment. The assignment will run this time, because it has to see what the second condition returns. Therefore, arg1 will be set to 0.
The correct snippet is the second.

Why || {} in parent[currentPart] = parent[currentPart] || {}

What is this javascript syntax?
parent[currentPart] = parent[currentPart] || {};
especially this part || {}
It is taken from this javascript code (at http://elegantcode.com/2011/01/26/basic-javascript-part-8-namespaces/)
// Creates a namespace
function namespace(namespaceString) {
var parts = namespaceString.split('.'),
parent = window,
currentPart = '';
var length = parts.length;
for (var i = 0; i < length; i++) {
currentPart = parts[i];
parent[currentPart] = parent[currentPart] || {};
parent = parent[currentPart];
}
return parent;
}
The || operator in javascript works a little differently than many other languages. In javascript, it evaluates to the first 'truthy' value, allowing a "fallthrough" sort of behavior.
Example:
var a = false;
var b = "asdf";
alert(a || b); //alert box with "asdf" since a was false
var c = true;
var d = "asdf";
var e = false;
alert(c || d || d); //alert box with true. d and e were never evaluated, so "asdf" isn't returned. This is called "short-circuiting" operation.
The && operator works similarly in that it evaluates to the first 'falsey' value or the last 'truthy' value if everything is true:
var a = true;
var b = "asdf";
alert(a && b); //alert box with "asdf"
alert(b && a): //alert box with true
var c = 6;
var d = 0;
alert(c && d); //alert box with 0
alert(d && c); //alert box with 0
In JS, logical operators (e.g. &&, ||) return a value, which, when part of an expression, can be used in an assignment.
Thus in the code below:
var a = false
, b = 'hello'
, c = (function() { return a || b })()
c is assigned the string 'hello', because || returns 'hello' to the return statement, which, in turn, returns it from the function and makes the assignment to c.
The definition of the || operator is:
expr1 || expr2 Returns expr1 if it can be converted to true; otherwise, returns expr2.
If parent[currentPart] does not exist, then the expression evaluates to an empty object ({}) and thus parent[currentPart] is initialized to that empty object. If it does exist, then it is left unchanged (that is, it is assigned to itself). The effect is to guarantee that parent[currentPart] always has a (non-falsy) value.
In the expression a = b || c, a will be set to b if b evaluates to true; otherwise, a will be set to c. This is often used because null and undefined both evaluate to false, so it's shorter than saying something like if (b == null) {a = c} else {a = b}.

Categories