All .filter's callback cares about is the truthy or falsey value returned inside it. Here, it'd be better to return that comparison directly, no conditional operator needed:

Copyconst interestingWords = words.filter(word => word.length > 5);

A construction like

Copyreturn word ? word.length > 5 : null

could make sense if you needed to check a sub-property, but only if the array element existed first, eg:

Copyconst objects = [
  null,
  { word: 'foo' },
  { word: 'barbar' },
  null
];

const interestingObjects = objects.filter(
  obj => obj ? obj.word.length > 5 : null
);
console.log(interestingObjects);
Run code snippetEdit code snippet Hide Results Copy to answer Expand

Answer from CertainPerformance on Stack Overflow
🌐
MDN Web Docs
developer.mozilla.org › en-US › docs › Web › JavaScript › Reference › Operators › Nullish_coalescing
Nullish coalescing operator (??) - JavaScript | MDN
It is not possible to combine either the AND (&&) or OR operators (||) directly with ??. A syntax error will be thrown in such cases. ... null || undefined ?? "foo"; // raises a SyntaxError true && undefined ?? "foo"; // raises a SyntaxError · Instead, provide parenthesis to explicitly indicate precedence: ... In this example, we will provide default values but keep values other than null or undefined. ... const nullValue = null; const emptyText = ""; // falsy const someNumber = 42; const valA = nullValue ??
Top answer
1 of 8
143

2020 Answer, It Exists!!!

You can now directly use ?. inline to test for existence. It is called the Optional Chaining Operator, supported by all modern browsers.

If a property exists, it proceeds to the next check, or returns the value. Any failure will immediately short-circuit and return undefined.

const example = {a: ["first", {b:3}, false]}

example?.a  // ["first", {b:3}, false]
example?.b  // undefined

example?.a?.[0]     // "first"
example?.a?.[1]?.a  // undefined
example?.a?.[1]?.b  // 3

domElement?.parentElement?.children?.[3]?.nextElementSibling

To ensure a default defined value, you can use ??. If you require the first truthy value, you can use ||.

example?.c ?? "c"  // "c"
example?.c || "c"  // "c"

example?.a?.[2] ?? 2  // false
example?.a?.[2] || 2  // 2

If you do not check a case, the left-side property must exist. If not, it will throw an exception.

example?.First         // undefined
example?.First.Second  // Uncaught TypeError: Cannot read property 'Second' of undefined

?. Browser Support - 94%, Oct '22

?? Browser Support - 94%

Node Support - v14+

2 of 8
31

Update 2020

This long-wished feature is now available in JavaScript!

I'll redirect to Gibolt's answer, which covers it well.

Original 2018 answer

  • There is no "null-safe navigation operator" in Javascript (EcmaScript 5 or 6), like ?. in C#, Angular templates, etc. (also sometimes called Elvis operator, when written ?:) , at least yet, unfortunately.

  • You can test for null and return some dependent expression in a single line with the ternary operator ?:, as already given in other answers :

(use === null to check only for nulls values, and == null to check for null and undefined)

    console.log(myVar == null ? myVar.myProp : 'fallBackValue');
  • in some cases, like yours, when your variable is supposed to hold an object, you can simply use the fact that any object is truthy whereas null and undefined are falsy values :

      if (myVar) 
          console.log(myVar.myProp)
      else
          console.log('fallbackValue')
    

    You can test for falsy values by coalescing to boolean with !! and make this inline :

      console.log(!!myVar ? myVar.myProp : 'fallbackValue');
    

    Be very careful though with this "falsy test", for if your variable is 0, '', or NaN, then it is falsy as well, even though it is not null/undefined.

🌐
MDN Web Docs
developer.mozilla.org › en-US › docs › Web › JavaScript › Reference › Operators › Conditional_operator
Conditional (ternary) operator - JavaScript | MDN
This operator is frequently used as an alternative to an if...else statement. function getFee(isMember) { return isMember ? "$2.00" : "$10.00"; } console.log(getFee(true)); // Expected output: "$2.00" console.log(getFee(false)); // Expected output: "$10.00" console.log(getFee(null)); // Expected output: "$10.00"
🌐
Scaler
scaler.com › home › topics › javascript › javascript ternary operator
JavaScript Ternary Operator - Scaler Topics
February 19, 2024 - Using the Ternary Operator in Javascript, we can handle these cases easily. ... Explanation: In the first console statement, we pass "Mark" to the function. So, the value of the variable name is "Mark".
🌐
Medium
medium.com › @dimplekollipara261 › simplify-your-javascript-code-with-ternary-and-nullish-coalescing-operators-57aaf765b416
Simplify Your JavaScript Code with Ternary(?) and Nullish Coalescing(??) Operators | by Dimple Kollipara | Medium
August 4, 2023 - The Nullish Coalescing Operator (??) is an operator introduced in ES2020 that offers a practical solution for setting default values when encountering “null” or “undefined” values in JavaScript.
🌐
SitePoint
sitepoint.com › blog › javascript › quick tip: how to use the ternary operator in javascript
Quick Tip: How to Use the Ternary Operator in JavaScript — SitePoint
November 6, 2024 - The first expression is executed if the condition is true, and the second if the condition is false. The ternary operator can be used for value assignment, executing expressions based on a condition, and checking if a variable is null or undefined.
Top answer
1 of 4
5

Empty string is also a falsy value.
If any() returns an empty string, !isMobile.any() ? false : true will return false, but you probably want true.

This means your code is incorrect for this case.

I'd just do something like isMobile.any() !== null.

2 of 4
1

As per the any() function, you are returning value of the following expression:

(isMobile.Android() || isMobile.BlackBerry() || isMobile.iOS() 
                             || isMobile.Opera() || isMobile.Windows())

Each of these functions can either return an Array or null as seen in the doc for match

So while evaluating the OR it will evaluate to the first truth value encountered and doesnt evaluate any further as the expression is already fit to be true. So, for example if the browser is android the expression evaluates to ["Android"]. If windows it will be ["Windows"]. If none of these, it will be null. Which makes it clear that any() can only return an Array or null.

isMobileBrowser should be true if it's any of these mobile browsers, which means isMobileBrowser should be true if:

any() evaluates to an Array

OR in other way:

If any() does not evaluate to null

which is:

$scope.isMobileBrowser = isMobile.any() instanceof Array;//looks messy
$scope.isMobileBrowser = (isMobile.any()).constructor === Array;//looks messy
$scope.isMobileBrowser = Array.isArray(isMobile.any());//looks messy
$scope.isMobileBrowser = Object.prototype.toString.call(isMobile.any()) 
                                   === "[object Array]";//looks messy

OR the other way:

$scope.isMobileBrowser = isMobile.any() !== null;
$scope.isMobileBrowser = !(isMobile.any() === null);
isMobileBrowser = !(Object.prototype.toString.call(isMobile.any()) 
                                   === "[object Null]");//looks messy

So we just discussed different ways to check for null and Array. You have two possible sets of outputs

  1. null value which is always false
  2. An Array which is always true (You can check this empty array scenario although that doesn't apply here)

So you can simply do the following to convert those to exact boolean without worrying much:

isMobileBrowser = Boolean(isMobile.any()); //to convert value to boolean
isMobileBrowser = !!isMobile.any(); //another way to convert to boolean
                                   //!!["Android"] is true
                                   //!!null is false

@rossipedia explains the !! well in his answer.

🌐
Reddit
reddit.com › r/learnjavascript › is it bad practice to use ternary with undefined or null?
r/learnjavascript on Reddit: Is it bad practice to use ternary with undefined or null?
September 28, 2023 -

For example, I have a game of snake in which each time the snake moves I check if it has eaten an apple, a powerup or itself. I could use multiple if statements, ie:

if(snakeAteSelf) {
    callFunction1
} 
if(snakeAtePowerUp) {
    callFunction2
}
if(snakeAteApple) {
    callfunction3
}

But instead I'm doing something more similar to

snakeAteSelf ? callFunction1 : null
snakeAtePowerup ? callFunction2 : null
snakeAteApple ? callFunction3 : null

But the null just stands out as odd looking to me, despite the rest of the code looking more concise.

EDIT: If anyone is interested in critiquing my game of snake you can play it here (press arrow keys to start, you wrap around edges so don't worry about hitting them) and view the code here.

Find elsewhere
🌐
GitConnected
levelup.gitconnected.com › using-the-ternary-operator-and-nullish-coalescing-b315237770fa
Using The Ternary Operator And Nullish Coalescing | by Alex Pickering | Level Up Coding
February 13, 2020 - So how does nullish coelescing differ from a normal ternary operator? Well the fundamental difference is that it will check to determine if a value is present. If the value is present, i.e. is not null or undefined then the value will be returned.
Top answer
1 of 2
3

You could expand your condition from just e to (e && e.className). That should prevent script errors resulting from passing in random junk or even non-element nodes.

Better, implement that condition as function hasClassName(e) { return ... } and use hasClassName(e) as your test.

EDIT: Replaced less-than-fully-compatible (typeof e=="object") && ('className' in e) condition, per comments. See also How do I check if an object has a property in JavaScript?

2 of 2
1

The code as it stands, will work if you pass in a string. However, if you want to be sure that you're only passing in a DOM element (it's better to be strict), you can modify your code to this:

function isNode(o){
  return (
    typeof Node === "object" ? o instanceof Node : 
    typeof o === "object" && typeof o.nodeType === "number" && typeof o.nodeName==="string"
  );
}    

function isElement(o){
  return (
    typeof HTMLElement === "object" ? o instanceof HTMLElement : //DOM2
    typeof o === "object" && o.nodeType === 1 && typeof o.nodeName==="string"
  );
}

var changeColorTo = {
    grey: function(e) {
        isNode(e) || isElement(e) ? (e.className = "grey") : "" ;
    },
    ...
}

For more information on how isNode and isElement work, take a look at this stackoverflow answer. This code will also ensure that you won't try to change the className attribute of a null or undefined variable since the first condition in each of those functions (o instanceof Node and o instanceof HTMLElement) will fail, which ensures that isNode and isElement will return false for null and undefined values.

Top answer
1 of 3
26

Let's do some fixing. First, this is how you pass optional (non-boolean) parameters in JS (the Good Waytm):

addFooListeners = function (panelType, handlers) {
    handlers        = handlers        || {};
    handlers.show   = handlers.show   || showFoo;
    handlers.hide   = handlers.hide   || hideFoo;
    handlers.commit = handlers.commit || commitFoo;

The above can be rewritten in a neater way using jQuery (not sure what the name of YUI equivalent to extend is):

handlers = $.extend({
    show  : showFoo, 
    hide  : hideFoo, 
    commit: commitFoo
}, handlers || {})

Now, using eval for this code is criminal. Say the object ns refers to is module, then you can do this instead of eval:

YAHOO.util.Event.addListener("show" + panelType, "click", handlers.show, module["panel_" + panelType], true);
YAHOO.util.Event.addListener("hide" + panelType, "click", handlers.hide, module["panel_" + panelType], true);
YAHOO.util.Event.addListener("commit" + panelType, "click", handlers.commit, module["panel_" + panelType], true);

Now, as you can see, you are assigning a lot of events in a similar fashion. Did you think of defining an addPanelListener function within your function?

function addPanelListener (event, panelType, handler) {
    YAHOO.util.Event.addListener(event + panelType, "click", handler, module["panel_" + panelType], true);
} 

addPanelListener("show"  , panelType, handlers.show);
addPanelListener("hide"  , panelType, handlers.hide);
addPanelListener("commit", panelType, handlers.commit):

Hope it helps.

2 of 3
7

It looks like you can reduce that ternary a bit by using && like this:

var handlers = {
    show:  ( overrides != null && overrides.show != null ? overrides.show : showFoo ),
    hide:  ( overrides != null && overrides.hide != null ? overrides.hide : hideFoo ),
    commit: ( overrides != null && overrides.commit != null ? overrides.commit : commitFoo )
}

I'm not too familiar with javascript but does the function parameter have to be checked against null? Like for example, can you further shorten the check by doing something like this?

show:  ( overrides && overrides.show ? overrides.show : showFoo ),
hide:  ( overrides && overrides.hide ? overrides.hide : hideFoo ),
// ...
🌐
RunJS
runjs.app › blog › using-the-ternary-operator-in-javascript
Using the Ternary Operator in JavaScript
October 14, 2022 - It's particularly important when you need to access properties of a variable, as attempting to access a property of a variable that is null or undefined will result in an error being thrown.
Top answer
1 of 13
363

First of all, a ternary expression is not a replacement for an if/else construct - it's an equivalent to an if/else construct that returns a value. That is, an if/else clause is code, a ternary expression is an expression, meaning that it returns a value.

This means several things:

  • use ternary expressions only when you have a variable on the left side of the = that is to be assigned the return value
  • only use ternary expressions when the returned value is to be one of two values (or use nested expressions if that is fitting)
  • each part of the expression (after ? and after : ) should return a value without side effects (the expression x = true returns true as all expressions return the last value, but it also changes x without x having any effect on the returned value)

In short - the 'correct' use of a ternary expression is

var resultofexpression = conditionasboolean ? truepart: falsepart;

Instead of your example condition ? x=true : null ;, where you use a ternary expression to set the value of x, you can use this:

 condition && (x = true);

This is still an expression and might therefore not pass validation, so an even better approach would be

 void(condition && x = true);

The last one will pass validation.

But then again, if the expected value is a boolean, just use the result of the condition expression itself

var x = (condition); // var x = (foo == "bar");

UPDATE

In relation to your sample, this is probably more appropriate:

defaults.slideshowWidth = defaults.slideshowWidth || obj.find('img').width()+'px';
2 of 13
32

No, it needs three operands. That's why they're called ternary operators.

However, for what you have as your example, you can do this:

if(condition) x = true;

Although it's safer to have braces if you need to add more than one statement in the future:

if(condition) { x = true; }

Edit: Now that you mention the actual code in which your question applies to:

if(!defaults.slideshowWidth)
    { defaults.slideshowWidth = obj.find('img').width()+'px'; }
🌐
DEV Community
dev.to › zougari47 › how-to-improve-your-code-quality-with-ternaryandor-operators-210k
How to improve your code quality with ternary,AND,OR, nullish coalescing operators - DEV Community
March 7, 2022 - If you are still using the or(||) and(&&) operators in just if statement you need to read this. If you don't know what is ternary operator, is a simplified conditional operator like if / else.
🌐
JavaScript.info
javascript.info › tutorial › the javascript language › javascript fundamentals
Nullish coalescing operator '??'
In practice though, we may want to use default value only when the variable is null/undefined. That is, when the value is really unknown/not set. ... The height || 100 checks height for being a falsy value, and it’s 0, falsy indeed. ... In practice, the zero height is often a valid value, that shouldn’t be replaced with the default. So ?? does just the right thing. The precedence of the ?? operator is the same as ||. They both equal 3 in the MDN table.
🌐
Go Make Things
gomakethings.com › the-nullish-coalescing-operator-in-vanilla-js-sorry-the-what-now
The nullish coalescing operator in vanilla JS (sorry, the what now?) | Go Make Things
But checking for both of those gets a bit too verbose. // if...else var logCount = function (num) { if (num !== null && num !== undefined) { console.log(`There are ${num} widgets left.`); } else { console.log('There are 42 widgets left.'); } }; // Ternary operator var logCount = function (num) { console.log(`There are ${num !== null && num !== undefined ?
🌐
Quora
quora.com › Which-is-more-efficient-for-checking-null-values-ternary-operators-or-if-statements
Which is more efficient for checking null values: ternary operators or if statements? - Quora
Answer: The two are equivalent constructs and therefore equally efficient. But there is a method that is slightly more efficient. The and and or operators generally do the job, given proper shortcut semantics, before you get to needing the ternary operator. You can almost always say [code ](this ...
🌐
Refine
refine.dev › home › blog › tutorials › how to use the javascript ternary operator
How to Use the JavaScript Ternary Operator | Refine
October 8, 2024 - false, 0, -0, 0n "", null, undefined, NaN and document.all. Expressions that evaluate to anything other than these are considered truthy. We use the JavaScript Ternary Operator when we need to control execution flow between two paths based on a conditional check that returns a Boolean.
🌐
Medium
medium.com › @justintulk › ternary-operators-and-coercing-truthy-falsy-if-statements-1e9296019fb
Ternary Operators and Coercing Truthy/Falsy if() Statements | by Justin Tulk | Medium
September 29, 2015 - The reason this works is because .getElementById() doesn’t return an empty array when it can’t find the element in question. Instead, it returns null.