How to check several local variables for the same if conditions - javascript

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() );

Related

Why can't I assign and then check a variable in the same if statement in Javascript?

In other words, why doesn't this show an alert?
var x;
if (x = 1 && x > 0) {
alert(x);
}
As far as I understand, x = 1 should assign 1 to x and also return 1. The x > 0 check is failing. Why?
Actually, the && operation will have precedence over the assignment.
In you case, x will be the result of 1 && x > 0 which is false.
var x;
if (x = 1 && x > 0) {
alert(x);
}
console.log(x); // false
You can enforce the order of operations using parentheses, as shown by Nina Scholz.
You need some parens to separate the assignment from the ongoing expression.
var x;
if ((x = 1) && x > 0) {
alert(x);
}

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

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 ===.

What should be the value of x?

what value should X have so this condition would work?
// insert code here
if (x == 1 && x === 2) {
console.log('Succes!');
}
X should be defined like so:
Object.defineProperty(window,'x',{
get: function() {
this.__tmp = this.__tmp || 2;
this.__tmp = 3-this.__tmp;
return this.__tmp;
}
});
Then:
if( x == 1 && x === 2)
MIGHT work. Demonstration
The following code should do the trick (Demo here):
x = {};
x.valueOf = function (){
x = 2; // this is important
return 1;
};
if (x == 1 && x === 2) {
console.log('Success !!!');
}
Explanation:
The statements are executed from left to right (so first x == 1, then x === 2). When checking x == 1, it will go to the valueOf function, which returns 1, so it will be true. But at the same time, x is changed to be 2, thus the next statement that will be checked (x === 2) will also be true.
PS: As far as I know, this has no practical application. However, it can lead to better understanding of how javascript works - which is the point of such questions :)
X can't hold a value equals to 1 and identical to 2 at the same time, this expression is logically incorrect.
There is no such value.
x === 2 checks if x equals exactly to 2, while 2 cannot be 1 at the same time.
Only the following would make sense:
if (x && x === 2) { ... }
(or getter overloading, as demonstrated in #Niet the Dark Absol's answer, which is not a pure case)
Using === (identity) operator it will never work, but it's possible to construct an object that will be "equal" (==) to 1 and 2 at the same time:
x = { valueOf: function() { return this.foo ? 2 : this.foo = 1 } }
console.log(x == 1 && x == 2) // true
"valueOf" is the method JS implicitly calls when you convert or compare an object to a number.
Needless to say, this exercise doesn't have any practical sense.

How Set local storage to 0 if undefined?

if localStorage["BestScore"] = undefined;
{
localStorage["BestScore"]=0;
maxScore=0;
}
var maxScore=localStorage["BestScore"];
var newScore=false
function drawScore(score) {
if (newScore == true && score < maxScore) {
newScore = false;
}
if (score > maxScore) {
newScore = true;
localStorage["BestScore"] = score;
if ([5, 10, 15, 20].indexOf(score) !== -1) {
play(sndMedal);
} else {
play(sndGain);
}
}
This code is to set the max score and then store it but it doesn't seem to set the local storage to 0 if undefined.
if localStorage["BestScore"] = undefined;
should be:
if( typeof localStorage["BestScore"] === 'undefined' )
However if you need to check a variable against undefined value, there is no need to invent any special method, since JavaScript has a typeof operator, which is simple, fast and cross-platform:
if (typeof localStorage["BestScore"] === "undefined") {
localStorage["BestScore"] = 0;
}
It returns a string indicating the type of the variable or other unevaluated operand. The main advantage of this method, compared to if (value === undefined) { ... }, is that typeof will never raise an exception in case if variable value does not exist.
if localStorage["BestScore"] = undefined;
should be ==
else you are assigning, not comparing.
use == or === as a comparison operator, then it should be fine

how to know what is x when x maybe several type

how to know what is x in js?
sometimes I have to write an function with parameter which has several type. such as test(x); I need to know what is x before I run the code .
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<div class="hello">hello</div>
<script type="text/javascript">
// the x var will be random 1 of 4 bellow , how to know what is it ?
var x = $('.hello')[0];
var x = ['1','2'];
var x = {'name':'jimmy'};
var x = 'hello';
if(???){
// alert x is a html node
}
if(???){
// alert x is a js arr
}
if(???){
// alert x is a js obj
}
if(???){
// alert x is a js str
}
</script>
if(typeof x === 'string'){
// string
} else {
if(x instanceof Array){
// array
} else if(x.nodeType){
// element
} else if(typeof x === 'object') {
// object
}
}
Fiddle
This would work in this case:
var x = $('.hello')[0];
var x = ['1','2'];
var x = {'name':'jimmy'};
var x = 'hello';
if(x === undefined){
// alert x is undefined
}else if(x === null){
// alert x is null
}else if('nodeType' in x){
// alert x is a html node
}else if(x instanceof Array){
// alert x is a js arr
}else if(typeof x == 'string'){
// alert x is a js str
}else if(x.constructor == Object){
// alert x is a js obj
}
The most used way, is to detect types by unique properties each object has (if(x.push)), because js is a 'duck type' language. But for this case the above code works fine.
Hope this helps. Cheers

Categories

Resources