How can I provide default value when a value is undefined? [duplicate] - javascript

Is there a null coalescing operator in Javascript?
For example, in C#, I can do this:
String someString = null;
var whatIWant = someString ?? "Cookies!";
The best approximation I can figure out for Javascript is using the conditional operator:
var someString = null;
var whatIWant = someString ? someString : 'Cookies!';
Which is sorta icky IMHO. Can I do better?

Update
JavaScript now supports the nullish coalescing operator (??). It returns its right-hand-side operand when its left-hand-side operand is null or undefined, and otherwise returns its left-hand-side operand.
Old Answer
Please check compatibility before using it.
The JavaScript equivalent of the C# null coalescing operator (??) is using a logical OR (||):
var whatIWant = someString || "Cookies!";
There are cases (clarified below) that the behaviour won't match that of C#, but this is the general, terse way of assigning default/alternative values in JavaScript.
Clarification
Regardless of the type of the first operand, if casting it to a Boolean results in false, the assignment will use the second operand. Beware of all the cases below:
alert(Boolean(null)); // false
alert(Boolean(undefined)); // false
alert(Boolean(0)); // false
alert(Boolean("")); // false
alert(Boolean("false")); // true -- gotcha! :)
This means:
var whatIWant = null || new ShinyObject(); // is a new shiny object
var whatIWant = undefined || "well defined"; // is "well defined"
var whatIWant = 0 || 42; // is 42
var whatIWant = "" || "a million bucks"; // is "a million bucks"
var whatIWant = "false" || "no way"; // is "false"

function coalesce() {
var len = arguments.length;
for (var i=0; i<len; i++) {
if (arguments[i] !== null && arguments[i] !== undefined) {
return arguments[i];
}
}
return null;
}
var xyz = {};
xyz.val = coalesce(null, undefined, xyz.val, 5);
// xyz.val now contains 5
this solution works like the SQL coalesce function, it accepts any number of arguments, and returns null if none of them have a value. It behaves like the C# ?? operator in the sense that "", false, and 0 are considered NOT NULL and therefore count as actual values. If you come from a .net background, this will be the most natural feeling solution.

Yes, it is coming soon. See proposal here and implementation status here.
It looks like this:
x ?? y
Example
const response = {
settings: {
nullValue: null,
height: 400,
animationDuration: 0,
headerText: '',
showSplashScreen: false
}
};
const undefinedValue = response.settings?.undefinedValue ?? 'some other default'; // result: 'some other default'
const nullValue = response.settings?.nullValue ?? 'some other default'; // result: 'some other default'
const headerText = response.settings?.headerText ?? 'Hello, world!'; // result: ''
const animationDuration = response.settings?.animationDuration ?? 300; // result: 0
const showSplashScreen = response.settings?.showSplashScreen ?? true; // result: false

If || as a replacement of C#'s ?? isn't good enough in your case, because it swallows empty strings and zeros, you can always write your own function:
function $N(value, ifnull) {
if (value === null || value === undefined)
return ifnull;
return value;
}
var whatIWant = $N(someString, 'Cookies!');

Nobody has mentioned in here the potential for NaN, which--to me--is also a null-ish value. So, I thought I'd add my two-cents.
For the given code:
var a,
b = null,
c = parseInt('Not a number'),
d = 0,
e = '',
f = 1
;
If you were to use the || operator, you get the first non-false value:
var result = a || b || c || d || e || f; // result === 1
If you use the new ?? (null coalescing) operator, you will get c, which has the value: NaN
vas result = a ?? b ?? c ?? d ?? e ?? f; // result === NaN
Neither of these seem right to me. In my own little world of coalesce logic, which may differ from your world, I consider undefined, null, and NaN as all being "null-ish". So, I would expect to get back d (zero) from the coalesce method.
If anyone's brain works like mine, and you want to exclude NaN, then this custom coalesce method (unlike the one posted here) will accomplish that:
function coalesce() {
var i, undefined, arg;
for( i=0; i < arguments.length; i++ ) {
arg = arguments[i];
if( arg !== null && arg !== undefined
&& (typeof arg !== 'number' || arg.toString() !== 'NaN') ) {
return arg;
}
}
return null;
}
For those who want the code as short as possible, and don't mind a little lack of clarity, you can also use this as suggested by #impinball. This takes advantage of the fact that NaN is never equal to NaN. You can read up more on that here: Why is NaN not equal to NaN?
function coalesce() {
var i, arg;
for( i=0; i < arguments.length; i++ ) {
arg = arguments[i];
if( arg != null && arg === arg ) { //arg === arg is false for NaN
return arg;
}
}
return null;
}

Logical nullish assignment, 2020+ solution
A new operator is currently being added to the browsers, ??=. This combines the null coalescing operator ?? with the assignment operator =.
NOTE: This is not common in public browser versions yet. Will update as availability changes.
??= checks if the variable is undefined or null, short-circuiting if already defined. If not, the right-side value is assigned to the variable.
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 Jan '22 - 89%
Mozilla Documentation

Yes, and its proposal is Stage 4 now. This means that the proposal is ready for inclusion in the formal ECMAScript standard. You can already use it in recent desktop versions of Chrome, Edge and Firefox, but we will have to wait for a bit longer until this feature reaches cross-browser stability.
Have a look at the following example to demonstrate its behavior:
// note: this will work only if you're running latest versions of aforementioned browsers
const var1 = undefined;
const var2 = "fallback value";
const result = var1 ?? var2;
console.log(`Nullish coalescing results in: ${result}`);
Previous example is equivalent to:
const var1 = undefined;
const var2 = "fallback value";
const result = (var1 !== null && var1 !== undefined) ?
var1 :
var2;
console.log(`Nullish coalescing results in: ${result}`);
Note that nullish coalescing will not threat falsy values the way the || operator did (it only checks for undefined or null values), hence the following snippet will act as follows:
// note: this will work only if you're running latest versions of aforementioned browsers
const var1 = ""; // empty string
const var2 = "fallback value";
const result = var1 ?? var2;
console.log(`Nullish coalescing results in: ${result}`);
For TypesScript users, starting off TypeScript 3.7, this feature is also available now.

?? vs || vs &&
None of the other answers compares all three of these. Since Justin Johnson's comment has so many votes, and since double question mark vs && in javascript was marked a duplicate of this one, it makes sense to include && in an answer.
First in words, inspired by Justin Johnson's comment:
|| returns the first "truey" value, else the last value whatever it is.
&& returns the first "falsey" value, else the last value whatever it is.
?? returns the first non-null, non-undefined value, else the last value, whatever it is.
Then, demonstrated in live code:
let F1,
F2 = null,
F3 = 0,
F4 = '',
F5 = parseInt('Not a number (NaN)'),
T1 = 3,
T2 = 8
console.log( F1 || F2 || F3 || F4 || F5 || T1 || T2 ) // 3 (T1)
console.log( F1 || F2 || F3 || F4 || F5 ) // NaN (F5)
console.log( T1 && T2 && F1 && F2 && F3 && F4 && F5 ) // undefined (F1)
console.log( T1 && T2 ) // 8 (T2)
console.log( F1 ?? F2 ?? F3 ?? F4 ?? F5 ?? T1 ) // 0 (F3)
console.log( F1 ?? F2) // null (F2)

After reading your clarification, #Ates Goral's answer provides how to perform the same operation you're doing in C# in JavaScript.
#Gumbo's answer provides the best way to check for null; however, it's important to note the difference in == versus === in JavaScript especially when it comes to issues of checking for undefined and/or null.
There's a really good article about the difference in two terms here. Basically, understand that if you use == instead of ===, JavaScript will try to coalesce the values you're comparing and return what the result of the comparison after this coalescence.

beware of the JavaScript specific definition of null. there are two definitions for "no value" in javascript.
1. Null: when a variable is null, it means it contains no data in it, but the variable is already defined in the code. like this:
var myEmptyValue = 1;
myEmptyValue = null;
if ( myEmptyValue === null ) { window.alert('it is null'); }
// alerts
in such case, the type of your variable is actually Object. test it.
window.alert(typeof myEmptyValue); // prints Object
Undefined: when a variable has not been defined before in the code, and as expected, it does not contain any value. like this:
if ( myUndefinedValue === undefined ) { window.alert('it is undefined'); }
// alerts
if such case, the type of your variable is 'undefined'.
notice that if you use the type-converting comparison operator (==), JavaScript will act equally for both of these empty-values. to distinguish between them, always use the type-strict comparison operator (===).

Note that React's create-react-app tool-chain supports the null-coalescing since version 3.3.0 (released 5.12.2019). From the release notes:
Optional Chaining and Nullish Coalescing Operators
We now support the optional chaining and nullish coalescing operators!
// Optional chaining
a?.(); // undefined if `a` is null/undefined
b?.c; // undefined if `b` is null/undefined
// Nullish coalescing
undefined ?? 'some other default'; // result: 'some other default'
null ?? 'some other default'; // result: 'some other default'
'' ?? 'some other default'; // result: ''
0 ?? 300; // result: 0
false ?? true; // result: false
This said, in case you use create-react-app 3.3.0+ you can start using the null-coalesce operator already today in your React apps.

There are two items here:
Logical OR
const foo = '' || 'default string';
console.log(foo); // output is 'default string'
Nullish coalescing operator
const foo = '' ?? 'default string';
console.log(foo); // output is empty string i.e. ''
The nullish coalescing operator (??) is 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.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing_operator

It will hopefully be available soon in Javascript, as it is in proposal phase as of Apr, 2020. You can monitor the status here for compatibility and support - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing_operator
For people using Typescript, you can use the nullish coalescing operator from Typescript 3.7
From the docs -
You can think of this feature - the ?? operator - as a way to “fall
back” to a default value when dealing with null or undefined. When we
write code like
let x = foo ?? bar();
this is a new way to say that the value foo will be used when it’s “present”; but when it’s null or undefined,
calculate bar() in its place.

Need to support old browser and have a object hierarchy
body.head.eyes[0] //body, head, eyes may be null
may use this,
(((body||{}) .head||{}) .eyes||[])[0] ||'left eye'

ECMAScript 2021 enabled two new features:
Nullish coalescing operator (??) which is a logical operator that returns its right-hand side operand when its left-hand side operand is either null or undefined, and otherwise returns its left-hand side operand.
let b = undefined ?? 5;
console.log(b); // 5
Logical nullish assignment (x ??= y) operator which only assigns if x has a nullish value (null or undefined).
const car = {speed : 20};
car.speed ??= 5;
console.log(car.speed);
car.name ??= "reno";
console.log(car.name);
More about Logical nullish assignment can be found here https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_nullish_assignment
More about Nullish coalescing operator can be found here
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing_operator

Now it has full support in latest version of major browsers like Chrome, Edge, Firefox , Safari etc. Here's the comparison between the null operator and Nullish Coalescing Operator
const response = {
settings: {
nullValue: null,
height: 400,
animationDuration: 0,
headerText: '',
showSplashScreen: false
}
};
/* OR Operator */
const undefinedValue = response.settings.undefinedValue || 'Default Value'; // 'Default Value'
const nullValue = response.settings.nullValue || 'Default Value'; // 'Default Value'
const headerText = response.settings.headerText || 'Hello, world!'; // 'Hello, world!'
const animationDuration = response.settings.animationDuration || 300; // 300
const showSplashScreen = response.settings.showSplashScreen || true; // true
/* Nullish Coalescing Operator */
const undefinedValue = response.settings.undefinedValue ?? 'Default Value'; // 'Default Value'
const nullValue = response.settings.nullValue ?? ''Default Value'; // 'Default Value'
const headerText = response.settings.headerText ?? 'Hello, world!'; // ''
const animationDuration = response.settings.animationDuration ?? 300; // 0
const showSplashScreen = response.settings.showSplashScreen ?? true; // false

Those who are using Babel, need to upgrade to the latest version to use nullish coalescing (??):
Babel 7.8.0 supports the new ECMAScript 2020 features by default: you
don't need to enable individual plugins for nullish coalescing (??),
optional chaining (?.) and dynamic import() anymore with preset-env
From https://babeljs.io/blog/2020/01/11/7.8.0

Chain multiple values / several values
"short circuit" is enabled: do not evaluate any further if one of the first values is valid
that means order matters, the most left values are prioritized
const value = first ?? second ?? third ?? "default";

I was trying to check if an input is null and then use the value accordingly. This is my code.
let valueToBeConsidered = !inputValue ? "trueCondition" : "falseCondition",
So if inputValue is null then valueToBeConsidered = falseCondition and if inputValue has a value then valueToBeConsidered = trueCondition

Related

Opposite of nullish coalescing operator

Nullish coalescing operator allows assigning a variable if it's not null or undefined, or an expression otherwise.
a = b ?? other
It is an improvement over previously used || because || will also assign other if b is empty string or other falsy, but not nullish value.
However, sometimes, we also use && for value assignment, for example
a = b && func(b)
where we only want to do func on b if it's not nullish, otherwise assign the nullish b.
Of course, && checks for falsiness, not nullishness. Is there a nullish version of &&?
To my knowledge, there is no such operator and also no proposal to add one. Instead you can rely on the standard way to check for nullish values: b == null
a = b == null ? b : func(b)
This will not answer the question since it was already answered by #str, I'm just posting this here because I don't have enough rep to comment on #Dalou's answer and don't want people to trip on that answer.
a = (b ?? false) && other
Is not the opposite of ??, since a will take the value of b if b is a falsy value other than undefined/null, like '' or 0 for example.
The opposite of ?? should set a to the value of other even if b is '' or 0.
ANSWER:
let a = 9;
if( a!==null || a!==undefined ){ /* actions */ };
if( (a??null) !== null ){ /* actions */ }
PROPOSAL:
const oo = console.log;
let a; // undefined, null
// Syntax proposal: !?
a !? oo('NOT Nullish coalescing operator');
// Logical NOT Nullish assignment:
let a = 7;
a !?= 5;
oo(a); // 5
let b, c = null;
b !?= 3;
oo(b); // undefined
c !?= 8;
oo(c); // null
I don't like it but here's my solution:
output = typeof input === 'boolean' && "other"
Truth table:
input -> output
--------------------
null -> false
undefined -> false
true -> "other"
false -> "other"

Is there a null-coalescing (Elvis) operator or safe navigation operator in javascript?

I'll explain by example:
Elvis Operator (?: )
The "Elvis operator" is a shortening
of Java's ternary operator. One
instance of where this is handy is for
returning a 'sensible default' value
if an expression resolves to false or
null. A simple example might look like
this:
def gender = user.male ? "male" : "female" //traditional ternary operator usage
def displayName = user.name ?: "Anonymous" //more compact Elvis operator
Safe Navigation Operator (?.)
The Safe Navigation operator is used
to avoid a NullPointerException.
Typically when you have a reference to
an object you might need to verify
that it is not null before accessing
methods or properties of the object.
To avoid this, the safe navigation
operator will simply return null
instead of throwing an exception, like
so:
def user = User.find( "admin" ) //this might be null if 'admin' does not exist
def streetName = user?.address?.street //streetName will be null if user or user.address is null - no NPE thrown
You can use the logical 'OR' operator in place of the Elvis operator:
For example displayname = user.name || "Anonymous" .
But Javascript currently doesn't have the other functionality. I'd recommend looking at CoffeeScript if you want an alternative syntax. It has some shorthand that is similar to what you are looking for.
For example The Existential Operator
zip = lottery.drawWinner?().address?.zipcode
Function shortcuts
()-> // equivalent to function(){}
Sexy function calling
func 'arg1','arg2' // equivalent to func('arg1','arg2')
There is also multiline comments and classes. Obviously you have to compile this to javascript or insert into the page as <script type='text/coffeescript>' but it adds a lot of functionality :) . Using <script type='text/coffeescript'> is really only intended for development and not production.
I think the following is equivalent to the safe navigation operator, although a bit longer:
var streetName = user && user.address && user.address.street;
streetName will then be either the value of user.address.street or undefined.
If you want it to default to something else you can combine with the above shortcut or to give:
var streetName = (user && user.address && user.address.street) || "Unknown Street";
2020 Update
JavaScript now has equivalents for both the Elvis Operator and the Safe Navigation Operator.
Safe Property Access
The optional chaining operator (?.) is currently a stage 4 ECMAScript proposal. You can use it today with Babel.
// `undefined` if either `a` or `b` are `null`/`undefined`. `a.b.c` otherwise.
const myVariable = a?.b?.c;
The logical AND operator (&&) is the "old", more-verbose way to handle this scenario.
const myVariable = a && a.b && a.b.c;
Providing a Default
The nullish coalescing operator (??) is currently a stage 4 ECMAScript proposal. You can use it today with Babel. It allows you to set a default value if the left-hand side of the operator is a nullary value (null/undefined).
const myVariable = a?.b?.c ?? 'Some other value';
// Evaluates to 'Some other value'
const myVariable2 = null ?? 'Some other value';
// Evaluates to ''
const myVariable3 = '' ?? 'Some other value';
The logical OR operator (||) is an alternative solution with slightly different behavior. It allows you to set a default value if the left-hand side of the operator is falsy. Note that the result of myVariable3 below differs from myVariable3 above.
const myVariable = a?.b?.c || 'Some other value';
// Evaluates to 'Some other value'
const myVariable2 = null || 'Some other value';
// Evaluates to 'Some other value'
const myVariable3 = '' || 'Some other value';
Javascript's logical OR operator is short-circuiting and can replace your "Elvis" operator:
var displayName = user.name || "Anonymous";
However, to my knowledge there's no equivalent to your ?. operator.
I've occasionally found the following idiom useful:
a?.b?.c
can be rewritten as:
((a||{}).b||{}).c
This takes advantage of the fact that getting unknown attributes on an object returns undefined, rather than throwing an exception as it does on null or undefined, so we replace null and undefined with an empty object before navigating.
i think lodash _.get() can help here, as in _.get(user, 'name'), and more complex tasks like _.get(o, 'a[0].b.c', 'default-value')
There is currently a draft spec:
https://github.com/tc39/proposal-optional-chaining
https://tc39.github.io/proposal-optional-chaining/
For now, though, I like to use lodash get(object, path [,defaultValue]) or dlv delve(obj, keypath)
Update (as of Dec 23, 2019):
optional chaining has moved to stage 4
For the former, you can use ||. The Javascript "logical or" operator, rather than simply returning canned true and false values, follows the rule of returning its left argument if it is true, and otherwise evaluating and returning its right argument. When you're only interested in the truth value it works out the same, but it also means that foo || bar || baz returns the leftmost one of foo, bar, or baz that contains a true value.
You won't find one that can distinguish false from null, though, and 0 and empty string are false values, so avoid using the value || default construct where value can legitimately be 0 or "".
Yes, there is! 🍾
Optional chaining is in stage 4 and this enables you to use the user?.address?.street formula.
If you can't wait the release, install #babel/plugin-proposal-optional-chaining and you can use it.
Here are my settings which works for me, or just read Nimmo's article.
// package.json
{
"name": "optional-chaining-test",
"version": "1.0.0",
"main": "index.js",
"devDependencies": {
"#babel/plugin-proposal-optional-chaining": "7.2.0",
"#babel/core": "7.2.0",
"#babel/preset-env": "^7.5.5"
}
...
}
// .babelrc
{
"presets": [
[
"#babel/preset-env",
{
"debug": true
}
]
],
"plugins": [
"#babel/plugin-proposal-optional-chaining"
]
}
// index.js
console.log(user?.address?.street); // it works
Here's a simple elvis operator equivalent:
function elvis(object, path) {
return path ? path.split('.').reduce(function (nestedObject, key) {
return nestedObject && nestedObject[key];
}, object) : object;
}
> var o = { a: { b: 2 }, c: 3 };
> elvis(o)
{ a: { b: 2 }, c: 3 }
> elvis(o, 'a');
{ b: 2 }
> elvis(o, 'a.b');
2
> elvis(o, 'x');
undefined
You can achieve roughly the same effect by saying:
var displayName = user.name || "Anonymous";
UPDATE SEP 2019
Yes, JS now supports this.
Optional chaining is coming soon to v8 read more
This is more commonly known as a null-coalescing operator. Javascript does not have one.
I have a solution for that, tailor it to your own needs, an excerpt from one of my libs:
elvisStructureSeparator: '.',
// An Elvis operator replacement. See:
// http://coffeescript.org/ --> The Existential Operator
// http://fantom.org/doc/docLang/Expressions.html#safeInvoke
//
// The fn parameter has a SPECIAL SYNTAX. E.g.
// some.structure['with a selector like this'].value transforms to
// 'some.structure.with a selector like this.value' as an fn parameter.
//
// Configurable with tulebox.elvisStructureSeparator.
//
// Usage examples:
// tulebox.elvis(scope, 'arbitrary.path.to.a.function', fnParamA, fnParamB, fnParamC);
// tulebox.elvis(this, 'currentNode.favicon.filename');
elvis: function (scope, fn) {
tulebox.dbg('tulebox.elvis(' + scope + ', ' + fn + ', args...)');
var implicitMsg = '....implicit value: undefined ';
if (arguments.length < 2) {
tulebox.dbg(implicitMsg + '(1)');
return undefined;
}
// prepare args
var args = [].slice.call(arguments, 2);
if (scope === null || fn === null || scope === undefined || fn === undefined
|| typeof fn !== 'string') {
tulebox.dbg(implicitMsg + '(2)');
return undefined;
}
// check levels
var levels = fn.split(tulebox.elvisStructureSeparator);
if (levels.length < 1) {
tulebox.dbg(implicitMsg + '(3)');
return undefined;
}
var lastLevel = scope;
for (var i = 0; i < levels.length; i++) {
if (lastLevel[levels[i]] === undefined) {
tulebox.dbg(implicitMsg + '(4)');
return undefined;
}
lastLevel = lastLevel[levels[i]];
}
// real return value
if (typeof lastLevel === 'function') {
var ret = lastLevel.apply(scope, args);
tulebox.dbg('....function value: ' + ret);
return ret;
} else {
tulebox.dbg('....direct value: ' + lastLevel);
return lastLevel;
}
},
works like a charm. Enjoy the less pain!
You could roll your own:
function resolve(objectToGetValueFrom, stringOfDotSeparatedParameters) {
var returnObject = objectToGetValueFrom,
parameters = stringOfDotSeparatedParameters.split('.'),
i,
parameter;
for (i = 0; i < parameters.length; i++) {
parameter = parameters[i];
returnObject = returnObject[parameter];
if (returnObject === undefined) {
break;
}
}
return returnObject;
};
And use it like this:
var result = resolve(obj, 'a.b.c.d');
* result is undefined if any one of a, b, c or d is undefined.
I read this article (https://www.beyondjava.net/elvis-operator-aka-safe-navigation-javascript-typescript) and modified the solution using Proxies.
function safe(obj) {
return new Proxy(obj, {
get: function(target, name) {
const result = target[name];
if (!!result) {
return (result instanceof Object)? safe(result) : result;
}
return safe.nullObj;
},
});
}
safe.nullObj = safe({});
safe.safeGet= function(obj, expression) {
let safeObj = safe(obj);
let safeResult = expression(safeObj);
if (safeResult === safe.nullObj) {
return undefined;
}
return safeResult;
}
You call it like this:
safe.safeGet(example, (x) => x.foo.woo)
The result will be undefined for an expression that encounters null or undefined along its path. You could go wild and modify the Object prototype!
Object.prototype.getSafe = function (expression) {
return safe.safeGet(this, expression);
};
example.getSafe((x) => x.foo.woo);
Jumping in very late, there's a proposal[1] for optional chaining currently at stage 2, with a babel plugin[2] available. It's not currently in any browser I am aware of.
https://github.com/tc39/proposal-optional-chaining
https://www.npmjs.com/package/#babel/plugin-proposal-optional-chaining
This was a problem for me for a long time. I had to come up with a solution that can be easily migrated once we get Elvis operator or something.
This is what I use; works for both arrays and objects
put this in tools.js file or something
// this will create the object/array if null
Object.prototype.__ = function (prop) {
if (this[prop] === undefined)
this[prop] = typeof prop == 'number' ? [] : {}
return this[prop]
};
// this will just check if object/array is null
Object.prototype._ = function (prop) {
return this[prop] === undefined ? {} : this[prop]
};
usage example:
let student = {
classes: [
'math',
'whatev'
],
scores: {
math: 9,
whatev: 20
},
loans: [
200,
{ 'hey': 'sup' },
500,
300,
8000,
3000000
]
}
// use one underscore to test
console.log(student._('classes')._(0)) // math
console.log(student._('classes')._(3)) // {}
console.log(student._('sports')._(3)._('injuries')) // {}
console.log(student._('scores')._('whatev')) // 20
console.log(student._('blabla')._('whatev')) // {}
console.log(student._('loans')._(2)) // 500
console.log(student._('loans')._(1)._('hey')) // sup
console.log(student._('loans')._(6)._('hey')) // {}
// use two underscores to create if null
student.__('loans').__(6)['test'] = 'whatev'
console.log(student.__('loans').__(6).__('test')) // whatev
well I know it makes the code a bit unreadable but it's a simple one liner solution and works great. I hope it helps someone :)
This was an interesting solution for the safe navigation operator using some mixin..
http://jsfiddle.net/avernet/npcmv/
// Assume you have the following data structure
var companies = {
orbeon: {
cfo: "Erik",
cto: "Alex"
}
};
// Extend Underscore.js
_.mixin({
// Safe navigation
attr: function(obj, name) { return obj == null ? obj : obj[name]; },
// So we can chain console.log
log: function(obj) { console.log(obj); }
});
// Shortcut, 'cause I'm lazy
var C = _(companies).chain();
// Simple case: returns Erik
C.attr("orbeon").attr("cfo").log();
// Simple case too, no CEO in Orbeon, returns undefined
C.attr("orbeon").attr("ceo").log();
// IBM unknown, but doesn't lead to an error, returns undefined
C.attr("ibm").attr("ceo").log();
I created a package that makes this a lot easier to use.
NPM jsdig
Github jsdig
You can handle simple things like and object:
const world = {
locations: {
europe: 'Munich',
usa: 'Indianapolis'
}
};
world.dig('locations', 'usa');
// => 'Indianapolis'
world.dig('locations', 'asia', 'japan');
// => 'null'
or a little more complicated:
const germany = () => 'germany';
const world = [0, 1, { location: { europe: germany } }, 3];
world.dig(2, 'location', 'europe') === germany;
world.dig(2, 'location', 'europe')() === 'germany';
?? would work in js which is equivalent to ?: in kotlin
Personally i use
function e(e,expr){try{return eval(expr);}catch(e){return null;}};
and for example safe get:
var a = e(obj,'e.x.y.z.searchedField');

Set a variable if undefined in JavaScript

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

What does "options = options || {}" mean in Javascript? [duplicate]

This question already has answers here:
What does the construct x = x || y mean?
(12 answers)
Closed 7 years ago.
I came over a snippet of code the other day that I got curious about, but I'm not really sure what it actually does;
options = options || {};
My thought so far; sets variable options to value options if exists, if not, set to empty object.
Yes/no?
This is useful to setting default values to function arguments, e.g.:
function test (options) {
options = options || {};
}
If you call test without arguments, options will be initialized with an empty object.
The Logical OR || operator will return its second operand if the first one is falsy.
Falsy values are: 0, null, undefined, the empty string (""), NaN, and of course false.
ES6 UPDATE: Now, we have real default parameter values in the language since ES6.
function test (options = {}) {
//...
}
If you call the function with no arguments, or if it's called explicitly with the value undefined, the options argument will take the default value. Unlike the || operator example, other falsy values will not cause the use of the default value.
It's the default-pattern..
What you have in your snippet is the most common way to implement the default-pattern, it will return the value of the first operand that yields a true value when converted to boolean.
var some_data = undefined;
var some_obj_1 = undefined;
var some_obj_2 = {foo: 123};
var str = some_data || "default";
var obj = some_obj1 || some_obj2 || {};
/* str == "default", obj == {foo: 123} */
the above is basically equivalent to doing the following more verbose alternative
var str = undefined;
var obj = undefined;
if (some_data) str = some_data;
else str = "default";
if (some_obj1) obj = some_obj1;
else if (some_obj2) obj = some_obj2;
else obj = {};
examples of values yield by the logical OR operator:
1 || 3 -> 1
0 || 3 -> 3
undefined || 3 -> 3
NaN || 3 -> 3
"" || "default" -> "default"
undefined || undefined -> undefined
false || true -> true
true || false -> true
null || "test" -> "test"
undefined || {} -> {}
{} || true -> {}
null || false || {} -> {}
0 || "!!" || 9 -> "!!"
As you can see, if no match is found the value of the last operand is yield.
When is this useful?
There are several cases, though the most popular one is to set the default value of function arguments, as in the below:
function do_something (some_value) {
some_value = some_value || "hello world";
console.log ("saying: " + some_value);
}
...
do_something ("how ya doin'?");
do_something ();
saying: how ya doin'?
saying: hello world
Notes
This is notably one of the differences that javascript have compared to many other popular programming languages.
The operator || doesn't implicitly yield a boolean value but it keeps the operand types and yield the first one that will evaluate to true in a boolean expression.
Many programmers coming from languages where this isn't the case (C, C++, PHP, Python, etc, etc) find this rather confusing at first, and of course there is always the opposite; people coming from javascript (perl, etc) wonders why this feature isn't implemented elsewhere.
Yes. The sample is equivalent to this:
if (options) {
options = options;
} else {
options = {};
}
The OR operator (||) will short-circuit and return the first truthy value.
Yes, that's exactly what it does.
Found another variation of this:
options || (options = {});
Seems to do the same trick.

Is there a "null coalescing" operator in JavaScript?

Is there a null coalescing operator in Javascript?
For example, in C#, I can do this:
String someString = null;
var whatIWant = someString ?? "Cookies!";
The best approximation I can figure out for Javascript is using the conditional operator:
var someString = null;
var whatIWant = someString ? someString : 'Cookies!';
Which is sorta icky IMHO. Can I do better?
Update
JavaScript now supports the nullish coalescing operator (??). It returns its right-hand-side operand when its left-hand-side operand is null or undefined, and otherwise returns its left-hand-side operand.
Old Answer
Please check compatibility before using it.
The JavaScript equivalent of the C# null coalescing operator (??) is using a logical OR (||):
var whatIWant = someString || "Cookies!";
There are cases (clarified below) that the behaviour won't match that of C#, but this is the general, terse way of assigning default/alternative values in JavaScript.
Clarification
Regardless of the type of the first operand, if casting it to a Boolean results in false, the assignment will use the second operand. Beware of all the cases below:
alert(Boolean(null)); // false
alert(Boolean(undefined)); // false
alert(Boolean(0)); // false
alert(Boolean("")); // false
alert(Boolean("false")); // true -- gotcha! :)
This means:
var whatIWant = null || new ShinyObject(); // is a new shiny object
var whatIWant = undefined || "well defined"; // is "well defined"
var whatIWant = 0 || 42; // is 42
var whatIWant = "" || "a million bucks"; // is "a million bucks"
var whatIWant = "false" || "no way"; // is "false"
function coalesce() {
var len = arguments.length;
for (var i=0; i<len; i++) {
if (arguments[i] !== null && arguments[i] !== undefined) {
return arguments[i];
}
}
return null;
}
var xyz = {};
xyz.val = coalesce(null, undefined, xyz.val, 5);
// xyz.val now contains 5
this solution works like the SQL coalesce function, it accepts any number of arguments, and returns null if none of them have a value. It behaves like the C# ?? operator in the sense that "", false, and 0 are considered NOT NULL and therefore count as actual values. If you come from a .net background, this will be the most natural feeling solution.
Yes, it is coming soon. See proposal here and implementation status here.
It looks like this:
x ?? y
Example
const response = {
settings: {
nullValue: null,
height: 400,
animationDuration: 0,
headerText: '',
showSplashScreen: false
}
};
const undefinedValue = response.settings?.undefinedValue ?? 'some other default'; // result: 'some other default'
const nullValue = response.settings?.nullValue ?? 'some other default'; // result: 'some other default'
const headerText = response.settings?.headerText ?? 'Hello, world!'; // result: ''
const animationDuration = response.settings?.animationDuration ?? 300; // result: 0
const showSplashScreen = response.settings?.showSplashScreen ?? true; // result: false
If || as a replacement of C#'s ?? isn't good enough in your case, because it swallows empty strings and zeros, you can always write your own function:
function $N(value, ifnull) {
if (value === null || value === undefined)
return ifnull;
return value;
}
var whatIWant = $N(someString, 'Cookies!');
Nobody has mentioned in here the potential for NaN, which--to me--is also a null-ish value. So, I thought I'd add my two-cents.
For the given code:
var a,
b = null,
c = parseInt('Not a number'),
d = 0,
e = '',
f = 1
;
If you were to use the || operator, you get the first non-false value:
var result = a || b || c || d || e || f; // result === 1
If you use the new ?? (null coalescing) operator, you will get c, which has the value: NaN
vas result = a ?? b ?? c ?? d ?? e ?? f; // result === NaN
Neither of these seem right to me. In my own little world of coalesce logic, which may differ from your world, I consider undefined, null, and NaN as all being "null-ish". So, I would expect to get back d (zero) from the coalesce method.
If anyone's brain works like mine, and you want to exclude NaN, then this custom coalesce method (unlike the one posted here) will accomplish that:
function coalesce() {
var i, undefined, arg;
for( i=0; i < arguments.length; i++ ) {
arg = arguments[i];
if( arg !== null && arg !== undefined
&& (typeof arg !== 'number' || arg.toString() !== 'NaN') ) {
return arg;
}
}
return null;
}
For those who want the code as short as possible, and don't mind a little lack of clarity, you can also use this as suggested by #impinball. This takes advantage of the fact that NaN is never equal to NaN. You can read up more on that here: Why is NaN not equal to NaN?
function coalesce() {
var i, arg;
for( i=0; i < arguments.length; i++ ) {
arg = arguments[i];
if( arg != null && arg === arg ) { //arg === arg is false for NaN
return arg;
}
}
return null;
}
Logical nullish assignment, 2020+ solution
A new operator is currently being added to the browsers, ??=. This combines the null coalescing operator ?? with the assignment operator =.
NOTE: This is not common in public browser versions yet. Will update as availability changes.
??= checks if the variable is undefined or null, short-circuiting if already defined. If not, the right-side value is assigned to the variable.
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 Jan '22 - 89%
Mozilla Documentation
Yes, and its proposal is Stage 4 now. This means that the proposal is ready for inclusion in the formal ECMAScript standard. You can already use it in recent desktop versions of Chrome, Edge and Firefox, but we will have to wait for a bit longer until this feature reaches cross-browser stability.
Have a look at the following example to demonstrate its behavior:
// note: this will work only if you're running latest versions of aforementioned browsers
const var1 = undefined;
const var2 = "fallback value";
const result = var1 ?? var2;
console.log(`Nullish coalescing results in: ${result}`);
Previous example is equivalent to:
const var1 = undefined;
const var2 = "fallback value";
const result = (var1 !== null && var1 !== undefined) ?
var1 :
var2;
console.log(`Nullish coalescing results in: ${result}`);
Note that nullish coalescing will not threat falsy values the way the || operator did (it only checks for undefined or null values), hence the following snippet will act as follows:
// note: this will work only if you're running latest versions of aforementioned browsers
const var1 = ""; // empty string
const var2 = "fallback value";
const result = var1 ?? var2;
console.log(`Nullish coalescing results in: ${result}`);
For TypesScript users, starting off TypeScript 3.7, this feature is also available now.
?? vs || vs &&
None of the other answers compares all three of these. Since Justin Johnson's comment has so many votes, and since double question mark vs && in javascript was marked a duplicate of this one, it makes sense to include && in an answer.
First in words, inspired by Justin Johnson's comment:
|| returns the first "truey" value, else the last value whatever it is.
&& returns the first "falsey" value, else the last value whatever it is.
?? returns the first non-null, non-undefined value, else the last value, whatever it is.
Then, demonstrated in live code:
let F1,
F2 = null,
F3 = 0,
F4 = '',
F5 = parseInt('Not a number (NaN)'),
T1 = 3,
T2 = 8
console.log( F1 || F2 || F3 || F4 || F5 || T1 || T2 ) // 3 (T1)
console.log( F1 || F2 || F3 || F4 || F5 ) // NaN (F5)
console.log( T1 && T2 && F1 && F2 && F3 && F4 && F5 ) // undefined (F1)
console.log( T1 && T2 ) // 8 (T2)
console.log( F1 ?? F2 ?? F3 ?? F4 ?? F5 ?? T1 ) // 0 (F3)
console.log( F1 ?? F2) // null (F2)
After reading your clarification, #Ates Goral's answer provides how to perform the same operation you're doing in C# in JavaScript.
#Gumbo's answer provides the best way to check for null; however, it's important to note the difference in == versus === in JavaScript especially when it comes to issues of checking for undefined and/or null.
There's a really good article about the difference in two terms here. Basically, understand that if you use == instead of ===, JavaScript will try to coalesce the values you're comparing and return what the result of the comparison after this coalescence.
beware of the JavaScript specific definition of null. there are two definitions for "no value" in javascript.
1. Null: when a variable is null, it means it contains no data in it, but the variable is already defined in the code. like this:
var myEmptyValue = 1;
myEmptyValue = null;
if ( myEmptyValue === null ) { window.alert('it is null'); }
// alerts
in such case, the type of your variable is actually Object. test it.
window.alert(typeof myEmptyValue); // prints Object
Undefined: when a variable has not been defined before in the code, and as expected, it does not contain any value. like this:
if ( myUndefinedValue === undefined ) { window.alert('it is undefined'); }
// alerts
if such case, the type of your variable is 'undefined'.
notice that if you use the type-converting comparison operator (==), JavaScript will act equally for both of these empty-values. to distinguish between them, always use the type-strict comparison operator (===).
Note that React's create-react-app tool-chain supports the null-coalescing since version 3.3.0 (released 5.12.2019). From the release notes:
Optional Chaining and Nullish Coalescing Operators
We now support the optional chaining and nullish coalescing operators!
// Optional chaining
a?.(); // undefined if `a` is null/undefined
b?.c; // undefined if `b` is null/undefined
// Nullish coalescing
undefined ?? 'some other default'; // result: 'some other default'
null ?? 'some other default'; // result: 'some other default'
'' ?? 'some other default'; // result: ''
0 ?? 300; // result: 0
false ?? true; // result: false
This said, in case you use create-react-app 3.3.0+ you can start using the null-coalesce operator already today in your React apps.
There are two items here:
Logical OR
const foo = '' || 'default string';
console.log(foo); // output is 'default string'
Nullish coalescing operator
const foo = '' ?? 'default string';
console.log(foo); // output is empty string i.e. ''
The nullish coalescing operator (??) is 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.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing_operator
It will hopefully be available soon in Javascript, as it is in proposal phase as of Apr, 2020. You can monitor the status here for compatibility and support - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing_operator
For people using Typescript, you can use the nullish coalescing operator from Typescript 3.7
From the docs -
You can think of this feature - the ?? operator - as a way to “fall
back” to a default value when dealing with null or undefined. When we
write code like
let x = foo ?? bar();
this is a new way to say that the value foo will be used when it’s “present”; but when it’s null or undefined,
calculate bar() in its place.
Need to support old browser and have a object hierarchy
body.head.eyes[0] //body, head, eyes may be null
may use this,
(((body||{}) .head||{}) .eyes||[])[0] ||'left eye'
ECMAScript 2021 enabled two new features:
Nullish coalescing operator (??) which is a logical operator that returns its right-hand side operand when its left-hand side operand is either null or undefined, and otherwise returns its left-hand side operand.
let b = undefined ?? 5;
console.log(b); // 5
Logical nullish assignment (x ??= y) operator which only assigns if x has a nullish value (null or undefined).
const car = {speed : 20};
car.speed ??= 5;
console.log(car.speed);
car.name ??= "reno";
console.log(car.name);
More about Logical nullish assignment can be found here https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_nullish_assignment
More about Nullish coalescing operator can be found here
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing_operator
Now it has full support in latest version of major browsers like Chrome, Edge, Firefox , Safari etc. Here's the comparison between the null operator and Nullish Coalescing Operator
const response = {
settings: {
nullValue: null,
height: 400,
animationDuration: 0,
headerText: '',
showSplashScreen: false
}
};
/* OR Operator */
const undefinedValue = response.settings.undefinedValue || 'Default Value'; // 'Default Value'
const nullValue = response.settings.nullValue || 'Default Value'; // 'Default Value'
const headerText = response.settings.headerText || 'Hello, world!'; // 'Hello, world!'
const animationDuration = response.settings.animationDuration || 300; // 300
const showSplashScreen = response.settings.showSplashScreen || true; // true
/* Nullish Coalescing Operator */
const undefinedValue = response.settings.undefinedValue ?? 'Default Value'; // 'Default Value'
const nullValue = response.settings.nullValue ?? ''Default Value'; // 'Default Value'
const headerText = response.settings.headerText ?? 'Hello, world!'; // ''
const animationDuration = response.settings.animationDuration ?? 300; // 0
const showSplashScreen = response.settings.showSplashScreen ?? true; // false
Those who are using Babel, need to upgrade to the latest version to use nullish coalescing (??):
Babel 7.8.0 supports the new ECMAScript 2020 features by default: you
don't need to enable individual plugins for nullish coalescing (??),
optional chaining (?.) and dynamic import() anymore with preset-env
From https://babeljs.io/blog/2020/01/11/7.8.0
Chain multiple values / several values
"short circuit" is enabled: do not evaluate any further if one of the first values is valid
that means order matters, the most left values are prioritized
const value = first ?? second ?? third ?? "default";
I was trying to check if an input is null and then use the value accordingly. This is my code.
let valueToBeConsidered = !inputValue ? "trueCondition" : "falseCondition",
So if inputValue is null then valueToBeConsidered = falseCondition and if inputValue has a value then valueToBeConsidered = trueCondition

Categories

Resources