٢٥ مارس ٢٠٢١
هذة المادة العلميه متاحه فقط باللغات الأتيه: English, Español, Français, Italiano, 日本語, 한국어, Русский, 简体中文. من فضلك, ساعدنا قم بالترجمه إلى عربي.

Nullish Coalescing Operator '??'

إضافة حديثة
هذه إضافة حديثة إلى اللغه. المتصفحات القديمه ربما تتطلب polyfills.

The nullish coalescing operator is written as two question marks ??.

As it treats null and undefined similarly, we’ll use a special term here, in this article. We’ll say that an expression is “defined” when it’s neither null nor undefined.

The result of a ?? b is:

  • if a is defined, then a,
  • if a isn’t defined, then b.

In other words, ?? returns the first argument if it’s not null/undefined. Otherwise, the second one.

The nullish coalescing operator isn’t anything completely new. It’s just a nice syntax to get the first “defined” value of the two.

We can rewrite result = a ?? b using the operators that we already know, like this:

result = (a !== null && a !== undefined) ? a : b;

Now it should be absolutely clear what ?? does. Let’s see where it helps.

The common use case for ?? is to provide a default value for a potentially undefined variable.

For example, here we show user if defined, otherwise Anonymous:

let user;

alert(user ?? "Anonymous"); // Anonymous (user not defined)

Here’s the example with user assigned to a name:

let user = "John";

alert(user ?? "Anonymous"); // John (user defined)

We can also use a sequence of ?? to select the first value from a list that isn’t null/undefined.

Let’s say we have a user’s data in variables firstName, lastName or nickName. All of them may be not defined, if the user decided not to enter a value.

We’d like to display the user name using one of these variables, or show “Anonymous” if all of them aren’t defined.

Let’s use the ?? operator for that:

let firstName = null;
let lastName = null;
let nickName = "Supercoder";

// shows the first defined value:
alert(firstName ?? lastName ?? nickName ?? "Anonymous"); // Supercoder

المقارنة مع ||

هذا مشابه جدًا للمعامل ||. في الحقيقة يمكننا استبدال ?? ب || في المثال السابق وسنحصل على نفس النتيجة. كما وصفنا في الفصل السابق.

The OR || operator can be used in the same way as ??, as it was described in the previous chapter.

For example, in the code above we could replace ?? with || and still get the same result:

let firstName = null;
let lastName = null;
let nickName = "Supercoder";

// shows the first truthy value:
alert(firstName || lastName || nickName || "Anonymous"); // Supercoder

Historically, the OR || operator was there first. It exists since the beginning of JavaScript, so developers were using it for such purposes for a long time.

On the other hand, the nullish coalescing operator ?? was added to JavaScript only recently, and the reason for that was that people weren’t quite happy with ||.

The important difference between them is that:

  • || returns the first truthy value.
  • ?? returns the first defined value.

In other words, || doesn’t distinguish between false, 0, an empty string "" and null/undefined. They are all the same – falsy values. If any of these is the first argument of ||, then we’ll get the second argument as the result.

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.

For example, consider this:

let height = 0;

alert(height || 100); // 100
alert(height ?? 100); // 0
  • The height || 100 checks height for being a falsy value, and it’s 0, falsy indeed.
    • so the result of || is the second argument, 100.
  • The height ?? 100 checks height for being null/undefined, and it’s not,
    • so the result is height “as is”, that is 0.

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 about the same as ||, just a bit lower. It equals 5 in the MDN table, while || is 6.

That means that, just like ||, the nullish coalescing operator ?? is evaluated before = and ?, but after most other operations, such as +, *.

So if we’d like to choose a value with ?? in an expression with other operators, consider adding parentheses:

let height = null;
let width = null;

// مهم: استخدم الأقواس
let area = (height ?? 100) * (width ?? 50);

alert(area); // 5000

Otherwise, if we omit parentheses, then as * has the higher precedence than ??, it would execute first, leading to incorrect results.

// without parentheses
let area = height ?? 100 * width ?? 50;

// ...works the same as this (probably not what we want):
let area = height ?? (100 * width) ?? 50;

Using ?? with && or ||

Due to safety reasons, JavaScript forbids using ?? together with && and || operators, unless the precedence is explicitly specified with parentheses.

هذا سينتج خطأ لغوي:

let x = 1 && 2 ?? 3; // Syntax error

The limitation is surely debatable, it was added to the language specification with the purpose to avoid programming mistakes, when people start to switch from || to ??.

استخدم الأقواس لتجنب الخطأ:

let x = (1 && 2) ?? 3; // تعمل دون مشاكل
alert(x); // 2

ملخص

  • The nullish coalescing operator ?? provides a short way to choose the first “defined” value from a list.

    يستخدم لوضع قيم افتراضية للمتغيرات:

    // اجعل height=100 إذا كان null أو undefined
    height = height ?? 100;
  • The operator ?? has a very low precedence, only a bit higher than ? and =, so consider adding parentheses when using it in an expression.

  • It’s forbidden to use it with || or && without explicit parentheses.

خريطة الدورة التعليمية

التعليقات

إقرأ هذا قبل أن تضع تعليقًا…
  • إذا كان لديك اقتراحات أو تريد تحسينًا - من فضلك من فضلك إفتح موضوعًا فى جيتهاب أو شارك بنفسك بدلًا من التعليقات.
  • إذا لم تستطع أن تفهم شيئّا فى المقال - وضّح ماهو.
  • إذا كنت تريد عرض كود استخدم عنصر <code> ، وللكثير من السطور استخدم <pre>، ولأكثر من 10 سطور استخدم (plnkr, JSBin, codepen…)