I have a variable that gets defined by user input. I want to replace its value only if it's undefined. But not if it's NaN. How can I do it?
I tried doing x || 0 but that also replaces NaN values.
You can do a strict comparison to the undefined value.
if (x === undefined) {
x = 0;
}
Naturally you'll want to be sure that x has been properly declared as usual.
If you have any sensitivities about the undefined value being plagued by really bad code (overwritten with a new value), then you can use the void operator to obtain a guaranteed undefined.You can do a strict comparison to the undefined value.
if (x === void 0) {
x = 0;
}
The operand to void doesn't matter. No matter what you give it, it'll return undefined.
These are all equivalent:
if (x === void undefined) {
x = 0;
}
if (x === void "foobar") {
x = 0;
}
if (x === void x) {
x = 0;
}
Ultimately if someone squashed undefined locally (it can't be squashed globally anymore), it's better to fix that bad code.
If you ever want to check for both null and undefined at the same time, and only those value, you can use == instead of ===.
if (x == null) {
x = 0;
}
Now x will be set to 0 if it was either null or undefined, but not any other value. You can use undefined in the test too. It's exactly the same.
if (x == undefined) {
x = 0;
}
From your question, it seems a little bit like you're specifically looking for number elements, even NaN. If you want to limit it to primitive numbers including NaN, then use typeof for the test.
if (typeof x !== "number") {
x = 0;
}
However, you'll lose numeric strings and other values that can successfully be converted to a number, so it depends on what you ultimately need.
For ES6 users you can simply do:
x ?? 0
?? is a Nullish coalescing operator:
a logical operator that returns its right-hand side operand when its left-hand side operand is null or undefined, and otherwise returns its left-hand side operand.
You can test using typeof (among other things):
if (typeof x == 'undefined') x = y;
Another approach is to test strict equality against undefined:
if (x === void 0) x = y
In this case we use void 0 as a safety since undefined can actually be redefined.
boy. Maybe you could try this,Hello, boy. Maybe you could try this,Hello, boy. Maybe you could try this,Hello, boy. Maybe you could try this,Hello, boy. Maybe you could try this
var a;//undefined
a = ~~a
console.log(a)//0
You can do this quite quickly with just a
x === undefined && (x = 0);
Related
Can anyone explain the meaning of the assign operator? What does it mean?
It came out as true but I'm unclear on how we reached to there.
Thanks!
var x = 0 !=1;
An assignment operator assigns a value to its left operand based on the value of its right operand. In this case true will be assigned to the variable x as 1!=0 (1 not equal-to 0) is true.
Order of operations (var x = (0 != 1))
Imagine you computed just 0 != 1. This is evidently a true statement, so this would evaluate to true. If you set x to the evaluation of 0 != 1, then you receive var x = true.
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.
Can someone explain to me why this returns an empty string ("") instead of a boolean (false)?
var x = "";
alert(x && x.length > 0);
...While this works as expected, returning true:
var y = "abc";
alert(y && y.length > 0);
I am basically just trying to do a simple shorthand check to see if a value exists in a variable (ensuring it's not undefined, null, or empty string).
I know I can do each test individually (x == null, typeof x == 'undefined', x == '') - I'm just trying to understand why Javascript returns a string on what looks to be a boolean test.
When a conditional operator in JavaScript is satisfied, it returns the last value evaluated.
var x = "";
alert(x && x.length > 0);
An empty string is falsey, so when you use just x in a condition, it will be false. Because you are using &&, if the LHS is false, then there is no reason to bother checking the RHS. This is short circuit evaluation. Therefore, the last evaluated part, the empty string, is returned to alert().
var y = "abc";
alert(y && y.length > 0);
A non empty string is truthy. So the LHS is true, and because it's an &&, the RHS is evaluated (it needs to be to know if the entire condition is true). The return value of y.length > 0 is true, so that is passed to your alert().
It is returning and empty string because x is already defined, just empty.
This causes the first part of your expression alert(x) to show an empty string.
If you need to check for a null/empty string, try something like this.
String.isNullOrWhiteSpace = function (str) {
if (typeof str === "string") {
var isNullOrWhiteSpace = false;
// Check for null string
if (str == null || typeof str === "undefined") isNullOrWhiteSpace = true;
// Check for string with whitespace
if (str.replace(/\s/g, '').length < 1) isNullOrWhiteSpace = true;
return isNullOrWhiteSpace;
}
if (typeof str === "undefined" || str == null) {
return true;
}
};
The conditional operations using the && (AND operator) will stop when:
One of the conditions evaluated to false
It successfully made it to the end by evaluating everything to true
The result of the conditional operations will be the last evaluated before stopping (not necessarily a boolean)
To force returning a real boolean, you can wrap everything around !!(...), example:
alert(typeof !!(...) === "boolean"); //will always be true no matter what conditions are inside
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/