Null合体演算子

This translation is incomplete. この記事の翻訳にご協力ください

Null合体演算子 (??)は論理演算子の一種です。この演算子は左辺がnullもしくはundefinedの場合に右の値を返し、それ以外の場合に左の値を返します。

OR演算子(||)と違い、null と undefined 以外のfalsyな値のときには左の値を返します。つまり、左辺が'' や 0 の場合は左の値を評価して返します。その他の例については以下を参照してください。

構文

leftExpr ?? rightExpr

説明

The nullish coalescing operator returns the results of the right hand-side expression if the left hand-side expression is either null or undefined.

Assigning a default value to a variable

Earlier, when one wanted to assign a default value to a variable, a common pattern was to use the logical OR operator (||):

let foo;

//  foo is never assigned any value so it is still undefined
let someDummyText = foo || 'Hello!';

However, due to || being a boolean logical operator, the left hand-side operand was coerced to a boolean for the evaluation and any falsy value (0, '', NaN, null, undefined) was not returned. This behavior may cause unexpected consequences if you consider 0, '', or NaN as valid values.

let count = 0;
let text = "";

let qty = count || 42;
let message = text || "hi!";
console.log(qty);     // 42 and not 0
console.log(message); // "hi!" and not ""

The nullish coalescing operator avoids this pitfall by only returning the second operand when the first one evaluates to either null or undefined (but no other falsy values):

let myText = ''; // An empty string (which is also a falsy value)

let notFalsyText = myText || 'Hello world';
console.log(notFalsyText); // Hello world

let preservingFalsy = myText ?? 'Hi neighborhood';
console.log(preservingFalsy); // '' (as myText is neither undefined nor null)

Short-circuiting

Like the OR and AND logical operators, the right-hand side expression is not evaluated if the left-hand side proves to be neither null nor undefined.

function A() { console.log('A was called'); return undefined;}
function B() { console.log('B was called'); return false;}
function C() { console.log('C was called'); return "foo";}

console.log( A() ?? C() );
// logs "A was called" then "C was called" and then "foo"
// as A() returned undefined so both expressions are evaluated

console.log( B() ?? C() );
// logs "B was called" then "false"
// as B() returned false (and not null or undefined), the right
// hand side expression was not evaluated

No chaining with AND or OR operators

It is not possible to combine both the AND (&&) and OR operators (||) directly with ??. A SyntaxError will be thrown in such cases.

null || undefined ?? "foo"; // raises a SyntaxError
true || undefined ?? "foo"; // raises a SyntaxError

However, providing parenthesis to explicitly indicate precedence is correct:

(null || undefined) ?? "foo"; // returns "foo"

Relationship with the optional chaining operator (?.)

The nullish coalescing operator treats undefined and null as specific values and so does the optional chaining operator (?.) which is useful to access a property of an object which may be null or undefined.

let foo = { someFooProp: "hi" };

console.log(foo.someFooProp?.toUpperCase());  // "HI"
console.log(foo.someBarProp?.toUpperCase()); // undefined

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 ?? "default for A";
const valB = emptyText ?? "default for B";
const valC = someNumber ?? 0;

console.log(valA); // "default for A"
console.log(valB); // "" (as the empty string is not null or undefined)
console.log(valC); // 42

仕様

Specification Status Comment
Proposal for the "nullish coalescing" operator Stage 3

ブラウザ実装状況

Update compatibility data on GitHub
デスクトップモバイルサーバー
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewAndroid 版 ChromeAndroid 版 FirefoxAndroid 版 OperaiOSのSafariSamsung InternetNode.js
Nullish coalescing operator (??)Chrome 完全対応 80Edge 完全対応 80Firefox 完全対応 72IE 未対応 なしOpera 未対応 なしSafari 完全対応 13.1WebView Android 完全対応 80Chrome Android 完全対応 80Firefox Android 未対応 なしOpera Android 未対応 なしSafari iOS 完全対応 13.4Samsung Internet Android 未対応 なしnodejs 未対応 なし

凡例

完全対応  
完全対応
未対応  
未対応

Implementation Progress

The following table provides a daily implementation status for this feature, because this feature has not yet reached cross-browser stability. The data is generated by running the relevant feature tests in Test262, the standard test suite of JavaScript, in the nightly build, or latest release of each browser's JavaScript engine.

関連情報