So, I'm working on a game, and I want it so that if any of the variables are "NaN" or undefined, variableThatTriggeredThis will be set to 0.
I didn't try anything so far, I have no ideas how I can fix it.
if(example == NaN || foo == NaN || bar == NaN) {
variableThatTriggeredThis = 0;
}
I also wanted to ask if there's a way to select every variable in the code, or for example multiple variables, just like var(one, two) == "100".
You can check variables directly. NaN or undefined are valued as false.
Then use Logical OR ||
expr1 || expr2 If expr1 can be converted to true, returns expr1; else, returns expr2
Example:
example = example || 0 ;
foo = foo || 0 ;
bar = bar || 0 ;
There are several ways you could write this. Here's one option using array destructuring:
let a = 10;
let b = 0/0; // NaN
let c; // undefined
const undefinedOrNaNCheck = value => (value === undefined || Number.isNaN(value)) ? 0 : value;
[a, b, c] = [a, b, c].map(undefinedOrNaNCheck);
console.log([a, b, c]);
To coerce a variable into a number (defaulting to 0):
example = isNaN(example) ? 0 : example * 1;
To process several variables, one approach is to create a parent object:
const scores = {};
scores.example = 10;
scores.foo = undefined;
scores.bar = 'not a number';
... allowing iteration like this:
Object.keys(scores).forEach(function(key) {
scores[key] = isNaN(scores[key]) ? 0 : scores[key] * 1;
});
Here's a working fiddle.
If you're supporting an older version of javascript (eg. older browsers) you'll need to use "var" instead of "const" and use a "for" loop instead of the "forEach" loop shown above.
Related
I know that I can test for a JavaScript variable and then define it if it is undefined, but is there not some way of saying
var setVariable = localStorage.getItem('value') || 0;
seems like a much clearer way, and I'm pretty sure I've seen this in other languages.
Yes, it can do that, but strictly speaking that will assign the default value if the retrieved value is falsey, as opposed to truly undefined. It would therefore not only match undefined but also null, false, 0, NaN, "" (but not "0").
If you want to set to default only if the variable is strictly undefined then the safest way is to write:
var x = (typeof x === 'undefined') ? your_default_value : x;
On newer browsers it's actually safe to write:
var x = (x === undefined) ? your_default_value : x;
but be aware that it is possible to subvert this on older browsers where it was permitted to declare a variable named undefined that has a defined value, causing the test to fail.
Logical nullish assignment, ES2020+ solution
New operators are currently being added to the browsers, ??=, ||=, and &&=. This post will focus on ??=.
This checks if left side is undefined or null, short-circuiting if already defined. If not, the right-side is assigned to the left-side variable.
Comparing Methods
// Using ??=
name ??= "Dave"
// Previously, ES2020
name = name ?? "Dave"
// or
if (typeof name === "undefined" || name === null) {
name = true
}
// Before that (not equivalent, but commonly used)
name = name || "Dave" // Now: name ||= "Dave"
Basic Examples
let a // undefined
let b = null
let c = false
a ??= true // true
b ??= true // true
c ??= true // false
Object/Array Examples
let x = ["foo"]
let y = { foo: "fizz" }
x[0] ??= "bar" // "foo"
x[1] ??= "bar" // "bar"
y.foo ??= "buzz" // "fizz"
y.bar ??= "buzz" // "buzz"
x // Array [ "foo", "bar" ]
y // Object { foo: "fizz", bar: "buzz" }
??= Browser Support Oct 2022 - 93%
??= Mozilla Documentation
||= Mozilla Documentation
&&= Mozilla Documentation
The 2018 ES6 answer is:
return Object.is(x, undefined) ? y : x;
If variable x is undefined, return variable y... otherwise if variable x is defined, return variable x.
ES2020 Answer
With the Nullish Coalescing Operator, you can set a default value if value is null or undefined.
const setVariable = localStorage.getItem('value') ?? 0;
However, you should be aware that the nullish coalescing operator does not return the default value for other types of falsy value such as 0 and ''.
However, do take note of the browser support. You may need to use a JavaScript compiler like Babel to convert it into something more backward compatible. If you are using Node.js, it has been supported since version 14.
I needed to "set a variable if undefined" in several places. I created a function using #Alnitak answer. Hopefully it helps someone.
function setDefaultVal(value, defaultValue){
return (value === undefined) ? defaultValue : value;
}
Usage:
hasPoints = setDefaultVal(this.hasPoints, true);
It seems more logical to check typeof instead of undefined? I assume you expect a number as you set the var to 0 when undefined:
var getVariable = localStorage.getItem('value');
var setVariable = (typeof getVariable == 'number') ? getVariable : 0;
In this case if getVariable is not a number (string, object, whatever), setVariable is set to 0
In our days you actually can do your approach with JS:
// Your variable is null
// or '', 0, false, undefined
let x = null;
// Set default value
x = x || 'default value';
console.log(x); // default value
So your example WILL work:
const setVariable = localStorage.getItem('value') || 0;
You can use any of below ways.
let x;
let y = 4;
x || (x = y)
in ES12 or after
let x;
let y = 4;
x ||= y;
If you're a FP (functional programming) fan, Ramda has a neat helper function for this called defaultTo :
usage:
const result = defaultTo(30)(value)
It's more useful when dealing with undefined boolean values:
const result2 = defaultTo(false)(dashboard.someValue)
var setVariable = (typeof localStorage.getItem('value') !== 'undefined' && localStorage.getItem('value')) || 0;
Ran into this scenario today as well where I didn't want zero to be overwritten for several values. We have a file with some common utility methods for scenarios like this. Here's what I added to handle the scenario and be flexible.
function getIfNotSet(value, newValue, overwriteNull, overwriteZero) {
if (typeof (value) === 'undefined') {
return newValue;
} else if (value === null && overwriteNull === true) {
return newValue;
} else if (value === 0 && overwriteZero === true) {
return newValue;
} else {
return value;
}
}
It can then be called with the last two parameters being optional if I want to only set for undefined values or also overwrite null or 0 values. Here's an example of a call to it that will set the ID to -1 if the ID is undefined or null, but wont overwrite a 0 value.
data.ID = Util.getIfNotSet(data.ID, -1, true);
Works even if the default value is a boolean value:
var setVariable = ( (b = 0) => b )( localStorage.getItem('value') );
It seems to me, that for current javascript implementations,
var [result='default']=[possiblyUndefinedValue]
is a nice way to do this (using object deconstruction).
Sorry, I'm a bit of a noob when it comes to javascript. But here is my problem:
The following function returns -1 when 0 is inputed
function foo(bar){
return bar || -1;
}
foo(0);
is there a nice and elegant way to allow the || operator to read 0 (specifically 0, not all falsy values) as a valid value so that the function retuns 0? Or do I have to do this:
function foo(bar){
if(bar === 0){
return 0;
} else {
return bar || -1;
}
}
foo(0);
Edit:
Thank you everyone for your answers!
For those wondering, the question was asked to find the solution to the same issue with optional parameters. The following code is an example of how it could be applied.
function Point(x,y,meta){ //meta is an optional parameter. In this case I wanted to set meta to 0, but it was being set to null.
this.x = x;
this.y = y;
//this.meta = meta || null; This line is the old code that would set meta to null when 0 is inputed.
this.meta = meta === 0 ? 0 : (meta || null); //the fix suggested by many users is applied here.
};
var foo = new Point(1,2,0);
console.log(foo.meta); //foo.meta is now 0 instead of null!
That's the way JavaScript works. All values are either truthy or falsy. Zero happens to be a falsy value. You can simplify your function with a ternary though.
function foo(bar) {
return bar === 0 ? 0 : (bar || -1);
}
The tightest you can get is to collapse your if-else in to a single return, a la:
return bar === 0 ? bar : (bar || -1);
Because || compares truthy/falsy values, you have to explicitly handle (using strong typing) the 0 case.
It's hard to tell from your question, but usually when I'm overriding the truthy/falsy nature of comparisons, it's to default a value. In that case, it's to detect if my function has been given an undefined value, and to use some sane default in its place.
You could rewrite foo like this using the ternary operator:
function foo(bar) {
return bar === 0 ? 0 : (bar || -1)
}
The syntax for the ternary operator is condition ? expr1 : expr2. If condition is truthy, it will return expr1, otherwise it will return expr2.
Here's more information on the ternary operator
The other approach is to look at the number of arguments received and set default value that way.
function foo(bar){
if (arguments.length === 0) {
return -1;
}
return bar;
}
function foo(bar){
return typeof bar === "undefined" || bar === null ? -1 : bar;
}
foo(0); // should give 0
foo(false); // should give false
var a; // undefined variable
foo(a); // should give -1
foo(null); // should give -1
var b = {}; // object
foo(b.a); // should give -1 (undefined property)
Well, the intention of this if is to check for missing (non-present) value. In JavaScript the value is missing if it is:
undefined
null
The best way to check something for undefined is to strictly (===) check its type for equality to "undefined" string - this way you don't get an exception if bar can't be evaluated.
But, if your expression is not undefined, you can then safely check its' value with comparison bar===null.
Thus, we have both cases covered and we are not getting exceptions.
In C I know true and false evaluate to 1 and 0 respectively. show in this case just prints to the screen... Not sure what's going on here. I'm expecting to get true back. This 1 is messing up my karma.
show(1 && true);
true
show(true && 1);
1
Simply put - that's how && is defined. In Javascript, a && b returns a if a is falsy and b if a is truthy.
Conversely a || b returns a if a is truthy and b if a is falsy.
This makes sense intuitively - if a is false in a && b, then why bother reading the rest of the expression? You already know the whole thing is false. So just return false. But Javascript makes the decision to return a, which is falsy, instead of making up the value false to return out of nowhere.
This is based on short-circuit evaluation common to all C-style languages.
It allows for much expressiveness in Javascript. For instance this pattern:
var foo = function(opts) {
opts = opts || {}
// ...
}
Implements an optional parameter opts. If opts is not passed in at all, opts = opts || {} will set opts to {}, so the rest of the code does not have to know opts wasn't passed.
In long-hand it is equivalent to the following:
var x = a || b; // is equivalent to
var x;
if(a) {
x = a;
}
else {
x = b;
}
and
var y = a && b; // is equivalent to
var y;
if(!a) {
y = a;
}
else {
y = b;
}
Therefore Javascript can be much more terse than C or Java, because simple if statements can be replaced by || or && entirely. Sometimes this makes the code more terse and less readable and more like Perl, other times it allows for new Javascript patterns, like opts = opts || {}.
Another use is in patterns like
var displayName = user.fullname || user.email;
Which means "use the full name if available; if not, fall back to email." I personally find this expressive and readable, but it's arguably terse and obscure depending on which part of the Javascript community you hail from. Because of examples like this, and essentially the fact that truthy values are far more diverse then falsy values, using short-circuit || is much more common than short-circuit &&, as in your question.
In the code below, because s is null d = "test"
but if s = "hello" then d would = "hello".
Is this correct as it works? what is the correct way to use ||
var s = null;
var d = s || "test";
alert(d);
|| is "or" ; and understanding what happens here is a bit trickery
var a=false;
var b=true;
result=a||b
will give "result" true (as b is true). What happens is:
'a' is checked - it is false
'b' is checked AFTERWARDS (as no "true" result has been obtained yet, and ONE "true" result would suffice to make the whole || operator be true) - the value of it will be assigned to the left side
if you had
var a=true;
var b="test";
result=a||b
result will yield true; as no other value needs to be checked by the logic of "||"
with
var a=null;
var b="test";
result=a||b;
a will be checked first - it is null, which converts to "false". b is "test", which is non-null, and converts to "true". so the value of b will be assigned.
And yes, this is a correct way to use || ; the feature you use is also called short-circuit evaluation (as it stops evaluating the boolean expression as early as possible)
This works, but if s evaluates to a 'falsy' value, you'll get your default, which might not be what you intended. A more robust, but wordy idiom is
d = (typeof s === "undefined") ? "test" : s;
Yes it is correct unless s is allowed to be blank or 0 which are also falsy values
var s = null;
var d = s || "test";
var s = 0;
var d = s || "test";
var s = "";
var d = s || "test";
All will result in d being "test"
|| is a logical operator. When s is not null then the condition of (s) is true so d is assigned the value of s, otherwise it is assigned 'test'
|| is the OR operator in javascript
so a||b means a OR b in simple terms
explanation of question you have asked is that id you simply do somethings like these in js you will ultimately get in the else block
if(null)
if(undefined)
so s||"test" will mean which ever is not null or undefined
which in this case is test
yes correct, || symbols just does the job of OR. when the first condition is true its gonna return that one.. else it will move to the next... simple as it is...
I have been doing some reading lately one article I read was from Opera.
http://dev.opera.com/articles/view/javascript-best-practices/
In that article they write this:
Another common situation in JavaScript
is providing a preset value for a
variable if it is not defined, like
so:
if(v){
var x = v;
} else {
var x = 10;
}
The shortcut notation for this is the
double pipe character:
var x = v || 10;
For some reason, I can't get this to work for me. Is it really possible to check to see if v is defined, if not x = 10?
--Thanks.
Bryan
That Opera article gives a poor description of what is happening.
While it is true that x will get the value of 10 if v is undefined. It is also true that x will be 10 if v has any "falsey" value.
The "falsey" values in javascript are:
0
null
undefined
NaN
"" (empty string)
false
So you can see that there are many cases in which x will be set to 10 besides just undefined.
Here's some documentation detailing the logical operators. (This one is the "logical OR".) It gives several examples of its usage for such an assignment.
Quick example: http://jsfiddle.net/V76W6/
var v = 0;
var x = v || 10;
alert( x ); // alerts 10
Assign v any of the falsey values that I indicated above, and you'll get the same result.
var x = v || 10;
That operator (the "logical" or "short-circuit" OR operator) would normally check the value of v, and if it is a "falsy" value (i.e. it would fail as a condition used in an if statement), 10 becomes the value of x, otherwise v does (and if 10 were a function, it would never be executed).
undefined, null, and 0 are all examples of falsy values that a variable can hold (yes, even the first one), and the operator (or if statement) acts accordingly. In contrast, all objects and arrays (not including null) are "truthy" values, which allows for such things as this (used in the Google Analytics tracker code):
var _gaq = _gaq || []; // Makes a new array _gaq if it is not already there
However, if the referenced variable is not even declared anywhere within the scope chain, then a JavaScript exception will occur.
One way to avoid this is by declaring all your global variables from the start:
var iAmAGlobalVariable; // Holds the value undefined by default
If this is not possible, you should use the typeof operator. It does not attempt to evaluate its operand, and thus an exception will not occur:
var x;
if(typeof v != 'undefined' && v) {
x = v;
} else {
x = 10;
}
Or even better, if you know that the variable would be a global variable, you can treat it as a property of the global (window) object:
var x = window.v || 10;
If v evaluates to false (for example, 0, null, false) then it won't work. You can manually check for undefined:
var x = v !== undefined ? v : 10;
I would use triple equals with ternary in a function for this.
function myTest(x){
return x === undefined ? true: false;
}
Only returns true if x is undefined
See
(http://www.impressivewebs.com/why-use-triple-equals-javascipt/)
and
(http://jsfiddle.net/V76W6/)
I would just use a try-catch
var x = 0;
try
{
x = v;
}
catch(err)
{
x = 10;
}
Here is how to get it working:
var v; //declare v as undefined
// v = 5; //if uncommented x will be 5
var x = v || 10;
alert(x); //output: 10
http://jsfiddle.net/uLLtu/1/