When can != be used instead of !==? - javascript

Consider the code snippet below from this AngularJS tutorial:
app.factory('Auth',
function ($firebaseSimpleLogin, FIREBASE_URL, $rootScope) {
var ref = new Firebase(FIREBASE_URL);
var auth = $firebaseSimpleLogin(ref);
var Auth = {
register: function (user) {
return auth.$createUser(user.email, user.password);
},
signedIn: function () {
return auth.user !== null;
},
logout: function () {
auth.$logout();
}
};
$rootScope.signedIn = function () {
return Auth.signedIn();
};
return Auth;
});
I understand the difference between != and !== is the first compares by reference and the second compares by value. Since the comparison here is to null, then why has the developer chosen to use !== instead of !=? Is my understanding correct that both would work here?

== / != operator only compares the value of the variables, not the type
=== / !== operator compares the type and the value of the variables
Some examples:
var varA = 5; // int
var varB = '5'; // string
var varC = 5; // int
if(varA == varB) // true (only value compared)
if(varA === varB) // false: because varB is of type string and varA of type int
if(varA == varC) // true
if(varA === varC) // true: because varA and varC are of the same type and have the same value

I often use "if(x != null)" to check if x is either null or undefined. It's safer than just saying "if(x)" since there are other falsey values besides null and undefined.

Here's an overview table, for your convenience: http://jsfiddle.net/QQcVw/1/
0 "" false null undefined
0 Y Y Y n n
"" Y Y Y n n
false Y Y Y n n
null n n n Y Y
undefined n n n Y Y
As you can see, == considers equal three empty "values" (0, "" and false) and two "non-values" (null and undefined). See javascript standard for the exact algorithm.
In most cases, it's a good idea to avoid == and always stick to ===.

Related

What does var n = (t.currentDevicePixelRatio = e || ("undefined" != typeof window && window.devicePixelRatio) || 1); mean?

var n = (t.currentDevicePixelRatio = e || ("undefined" != typeof window && window.devicePixelRatio) || 1);
Can someone tell me what this means? I know "||" means "OR", and I know that an expression like
n = n || {}
is setting the value of n to an empty object if n is a falsy value. But what happens what you have an equals sign in there? And the second component is even more weird to me.
Let's add some whitespace to make it more readable:
var n = (
t.currentDevicePixelRatio = e
||
(
"undefined" != typeof window
&&
window.devicePixelRatio
)
||
1
);
JavaScript expressions are evaluated left-to-right, parentheses-first. So the evaluation order is:
Copy the value of e into t.currentDevicePixelRatio.
The value of e is then emitted by the assignment = statement.
If that value is falsy, then evaluate the right-hand-side of the ||:
So if e is not null (or undefined or an empty string) then that's that and the value of e is also assigned to n and the expression completes.
Otherwise, if window is defined (i.e. this script is running in a web-browser, as opposed to Node.js) then copy the value of window.devicePixelRatio into t.currentDevicePixelRatio and also into n.
If window.devicePixelRatio is undefined then use 1 for both t.currentDevicePixelRatio and n.
Here is how the individual steps break down to:
var n;
if (e) {
t.currentDevicePixelRatio = e;
n = t.currentDevicePixelRatio;
} else if ("undefined" != typeof window && window.devicePixelRatio) {
t.currentDevicePixelRatio = window.devicePixelRatio;
n = t.currentDevicePixelRatio;
} else {
t.currentDevicePixelRatio = 1;
n = t.currentDevicePixelRatio;
}

What does this condition do in ternary?

Javascript Ternary Condition
I have javascript with this condition, what is this?
var y = (typeof x !== undefined) ? x || 0 : 1;
This (typeof x !== undefined) ? x || 0 : 1; is going to return always true because the typeof operator will return a string.
That condition should compare a string as follow:
(typeof x !== 'undefined') ? x || 0 : 1;
var x;
var str = typeof x !== 'undefined' ? x || 0 : 1;
console.log(str);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Conditional (ternary) Operator explanation:
+--- When condition is true
|
| +--- When condition is false
| |
| |
v v
typeof x !== 'undefined' ? x || 0 : 1;
^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| +---- The condition should be:
| (x === undefined ? 1 : x || 0)
|
+--- Checks for the type of x
Code refactored
var x = 4;
var str = x === undefined ? 1 : x || 0;
console.log(str);// should return 4
var y;
str = y === undefined ? 1 : y || 0;
console.log(str);// should return 1
y = null;
str = y === undefined ? 1 : y || 0;
console.log(str);// should return 0
y = 5;
str = y === undefined ? 1 : y || 0;
console.log(str);// should return 5
y = 5-"5";
str = y === undefined ? 1 : y || 0;
console.log(str); // should return 0
.as-console-wrapper { max-height: 100% !important; top: 0; }
Docs
Conditional (ternary) Operator
typeof
First, there is an error with the condition:
(typeof x !== undefined)
because you are comparing a type against a value.
typeof always returns a string, while undefined is a value. So, whatever type x is, it will be returned as as string. Even if it's value is undefined, "undefined" (notice the quotes?) will be returned as its type and since the string "undefined" has a typeof === "string", the condition will actually branch into the true section, even when x actually is undefined.
So, it needs to be: (typeof x !== "undefined").
Or, you could test the value of x against the value undefined:
(x !== undefined)
But, you can't mix and match values and types.
Now, assuming we correct that, the next part (the true branch):
x || 0
Simply returns x, as long as it is not "falsy" (that is, any value that would convert to the Boolean false). 0, false, NaN, undefined, "" or null are all falsy. So, if x is not falsy, x is returned. If x is falsy, then 0 is returned. This is a way to provide a default return value in case the first value doesn't exist. But, the logic is a bit off here, because if the code has entered the true branch, it's because x is not undefined, which means it's "truthy". And, if it's truthy, then we can safely just return x. So, it really should just be:
x
Finally, the last part (the false branch)
1
Is what will be returned if the original condition is false. In this case, if x is undefined.
So, the code has flaws in it and really should be:
(typeof x !== "undefined") ? x : 1
EXTRA CREDIT:
In reality, any expression you place into the condition of an if statement is going to be converted to a Boolean for the if to do its job. If all you need to know is if x is not a "falsy" value, then all you need to do is write:
x ? x : 1;
The x will be converted to a Boolean.
If it's true (truthy), then x is returned.
If it's false (falsy), then 1 is returned.
Examples:
function testX(x){
return x ? x : 1;
}
// Truthy:
console.log(testX(10)); // 10
console.log(testX({})); // {}
console.log(testX(true)); // true
console.log(testX("something")); // "something"
// Falsy:
console.log(testX("")); // 1
console.log(testX()); // 1
console.log(testX(4-"Z")); // 1 because 4-"Z" == NaN
console.log(testX(false)); // 1
console.log(testX(0)); // 1
console.log(testX(null)); // 1
The condition
(typeof x !== undefined)
asks if x is not of type undefined. Or, if x is defined. This will include any value or even null.
...? x || 0
If so, the expression evaluates to this. Which is the value of x in most cases or 0 if x is anything evaluated to be boolean false, e.g., null, false, etc.
... : 1;
Otherwise (i.e. case when x is undefined), evaluates to 1.
Typing in Javascript is complicated (in my opinion), sometimes it is not easy to remember what it is when you're comparing mixed type stuff, see https://dorey.github.io/JavaScript-Equality-Table/ for a summary matrix.
Admitting that you have a left-hand operand, it does the same thing as :
var y;
if(typeof x !== undefined) {
if(x)
y = x;
else
y = 0;
}
else
y = 1;

That Operator || in console.log() works like || operator?

How it's work for example;
let x;
console.log(x || 2); // 2
if
let x = 4;
console.log(x || 2); // 4
if
let x = 5;
let y = 7;
console.log( y || x || 2);
it's mean that console.log() write first value that is true ?
What you're seeing isn't related to console.log. It's called short circuiting.
When comparing values with ||, it will always return the first truthy value. If no truthy values are present, it will return the last value being compared.
let a = false || true;
let b = false || null || 'b';
let c = undefined || !a || 10;
let d = undefined || false || null; // no truthy values
console.log(a); // true
console.log(b); // 'b'
console.log(c); // 10
console.log(d); // null
let x = 5;
let y = 7;
console.log( y || x || 2); //return 7
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.
Documentation: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_Operators

How to clear text field using javascript with a condition?

I want if I clear the text field #t1, text field #d1 should clear. But last two lines dont do it....
function utl()
{
var a = document.getElementById('t1');
var z = document.getElementById('d1');
if (a!=0)
{
var y = parseFloat(a.value) * 100;
y = y || 0;
z.value = y.toFixed(2);
}
else if (a==0)
z.value = 0;
else if (a=='')
z='';
a is a DOM element, and so it will always be != 0 as the != operator will coerce it to a string, and then to a number, and that number will be != 0.
You probably wanted to use the .value property:
var a = document.getElementById('t1').value;
But you'd still have a problem: The value of an input is always a string. In JavaScript, the == and != operators do type coercion, and "" is == 0. So your third statement, z='', will never be reached.
You can use the strict equality operators to figure out what's going on:
var a = document.getElementById('t1').value;
var z = document.getElementById('d1');
if (a === "") { // <== Note! === rather than ==
z.value = "";
} else {
a = +a; // Convert to number intentionally
if (a != 0) {
var y = a * 100;
y = y || 0;
z.value = y.toFixed(2);
} else if (a == 0) {
z.value = "0";
}
}
The strict equality (===) and inequality (!==) operators don't do type coercion, so although "" == 0 is true, "" === 0 is false.
That line where I converted to a number:
a = +a;
...is only one of the many options available. Using +str to convert to a number is the strictest way, but you don't have direct control over the number base. You could also use:
a = parseInt(a, 10); // If you're expecting an integer, or
a = parseFloat(a); // If it may have a fractional portion
...assuming you want base 10 (decimal), but note that they ignore trailing characters, and so parseInt("123laksdjflk", 10) is 123. In contrast, +str (or Number(str)) will say that's Nan because they consider the entire string, not just the first part.

How to check several local variables for the same if conditions

Alright, I find the code below to be quite repetitive and annoying. Any other way to refactor the code without using an array as a starting point (that is, to avoid using array[x], array[y], array[z] later on in the code as a result of starting with an array because x,y,z are completely unrelated and it makes no sense to group them for the sake of readability)
var x = "";
var y = "";
var z = "";
...
...variables get set
if(x != undefined && x != "")
doSomethingHere();
if(y != undefined && y != "")
doSomethingThere();
if(z != undefined && z != "")
doSomethingElse();
...
At very least you can factor out your validation rules to their own function:
function IsValid(x)
{
return (x != undefined && x != "");
}
var x = "";
var y = "";
var z = "";
//...
//...variables get set
if(IsValid(x)) doSomething();
if(IsValid(y)) doSomething();
if(IsValid(z)) doSomething();
In addition to what joel said you could also do the following:
function doOnValid(x, func){
if(x != undefined && x != "") func();
}
Then you could do:
doOnValid(x, doSomething);
doOnValid(y, doSomethingElse);
doOnvalid(z, function() { /*Yay lambda function*/ });
If you're trying to avoid repetition, be it vertical (var x;\r\n;var y;\r\n...) or horizontal (if (x || y || z || ...), a nice way to tidy things up is to gather your variables into an object as properties:
var vars = {
x: 42,
y: "",
z: undefined
};
for (var v in vars) {
var value = vars[v];
if (value != undefined && value != "") {
doSomething();
}
}
On top of that, if the action to be taken is different for each variable, you can also define an "actions" structure:
var actions = {
x: doSomething,
y: doSomethingElse,
z: doSomething
};
for (var v in vars) {
var value = vars[v];
if (value != undefined && value != "") {
actions[v]();
}
}
Is there a reason you initialize x,y and z to "" ?
If you just do
var x;
..... maybe set x .....
if (x)
doSomething()
You save quite a lot of fuzz. You can do the same for y and z ;) The initial value of x is undefined, which you can check with if (x), which means the same as if (x != undefined)
First of all, because both undefined and the empty string ("") evaluate as "false" in javascript, you can change your conditionals to:
if (x)
doSomething();
if (y)
doSomething();
if (z)
doSomething();
If the Something to be Done is always the same, you can certainly do
if (x || Y || z)
doSomething();
I'm guessing the original should have used y != undefined and doSomething () is the same function in all cases:
if((x != undefined && x != "") ||
(y != undefined && y != "") ||
(z != undefined && z != ""))
doSomething();
So to follow up on krosenvold's answer I think what you want is
var x;
var y;
var z;
// do stuff
if (x||y||z)
doSomething();
Which is much neater
This is about as concise as I can make it, assuming you want a unique action for each condition.
(x && doX());
(y && doY());
(z && doZ());
This works because your particular variable test just reduces to the value of the variable. You can, of course, also write a custom condition function:
function is_valid(x){
// return true or false
}
( is_valid(x) && doX() );
( is_valid(y) && doY() );
( is_valid(z) && doZ() );

Categories

Resources