Есть ли в JavaScript оператор "нулевого слияния"?

Есть ли в Javascript пустой оператор слияния?

Например, в C# я могу сделать это:

String someString = null;
var whatIWant = someString ?? "Cookies!";

Лучшее приближение, которое я могу выяснить для Javascript, это использование условного оператора:

var someString = null;
var whatIWant = someString ? someString : 'Cookies!';

Который является Сорти Ики ИМХО. Могу ли я сделать лучше?

21 ответ

Решение

JavaScript-эквивалент оператора C# NULL (??) использует логическое ИЛИ (||):

var whatIWant = someString || "Cookies!";

Есть случаи (поясненные ниже), что поведение не будет соответствовать поведению C#, но это общий, краткий способ назначения значений по умолчанию / альтернативных значений в JavaScript.


осветление

Независимо от типа первого операнда, если приведение его к логическому результату приводит к false, назначение будет использовать второй операнд. Остерегайтесь всех случаев ниже:

alert(Boolean(null)); // false
alert(Boolean(undefined)); // false
alert(Boolean(0)); // false
alert(Boolean("")); // false
alert(Boolean("false")); // true -- gotcha! :)

Это означает:

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

это решение работает как функция объединения SQL, оно принимает любое количество аргументов и возвращает ноль, если ни один из них не имеет значения. Ведет себя как C#?? оператор в том смысле, что "", false и 0 считаются NOT NULL и поэтому считаются фактическими значениями. Если вы пришли из.net фона, это будет самое естественное решение для чувства.

Да, это скоро. Смотрите предложение здесь и статус реализации здесь.

Это выглядит так:

x ?? y

пример

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

Если || в качестве замены C# ?? не достаточно хорош в вашем случае, потому что он глотает пустые строки и нули, вы всегда можете написать свою собственную функцию:

 function $N(value, ifnull) {
    if (value === null || value === undefined)
      return ifnull;
    return value;
 }

 var whatIWant = $N(someString, 'Cookies!');

Никто не упомянул здесь потенциал для NaN, который - для меня - также нулевое значение. Итак, я решил добавить свои два цента.

Для данного кода:

var a,
    b = null,
    c = parseInt('Not a number'),
    d = 0,
    e = '',
    f = 1
;

Если бы вы использовали || Оператор, вы получите первое не ложное значение:

var result = a || b || c || d || e || f; // result === 1

Если вы используете типичный метод объединения, как выложено здесь, вы получите c, который имеет значение: NaN

var result = coalesce(a,b,c,d,e,f); // result.toString() === 'NaN'

Ничто из этого не кажется мне правильным. В моем собственном маленьком мире логики слияния, который может отличаться от вашего мира, я считаю, что undefined, null и NaN - все это "ноль". Итак, я бы ожидал, чтобы вернуться d (ноль) из метода слияния.

Если чей-то мозг работает как мой, и вы хотите исключить NaN, тогда этот метод выполнит это:

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;
}

Для тех, кто хочет, чтобы код был как можно более коротким, и не возражал против некоторой нехватки ясности, вы можете также использовать это, как предложено @impinball. Это использует тот факт, что NaN никогда не равен NaN. Вы можете прочитать больше об этом здесь: Почему NaN не равен 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;
}

Логическое нулевое назначение, решение 2020+

В браузеры в настоящее время добавляется новый оператор, ??=. Это объединяет нулевой оператор объединения?? с оператором присваивания =.

Примечание: Это не распространено в версиях браузера открытых еще. Будет обновляться по мере изменения доступности.

??=проверяет, является ли переменная неопределенной или нулевой, закорачивает, если она уже определена. Если нет, переменной присваивается правое значение.

Основные примеры

let a          // undefined
let b = null
let c = false

a ??= true  // true
b ??= true  // true
c ??= true  // false

Примеры объектов / массивов

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" }

Поддержка браузеров, сентябрь 2020 г. - 3,7%

Документация Mozilla

против против

Ни один из других ответов не сравнивает все три из них. Поскольку комментарий Джастина Джонсона имеет так много голосов, и поскольку двойной вопросительный знак против &amp;amp;&amp;amp; в javascript был помечен как дубликат этого, имеет смысл включить его в ответ.

Сначала словами, вдохновленными комментарием Джастина Джонсона:

  • ||возвращает первое «истинное» значение, иначе последнее значение, каким бы оно ни было.

  • &&возвращает первое «ложное» значение, иначе последнее значение, каким бы оно ни было.

  • ??возвращает первое ненулевое, не неопределенное значение, иначе последнее значение, каким бы оно ни было.

Далее демонстрируется в живом коде:

Да, и его предложение сейчас находится на стадии 4. Это означает, что предложение готово для включения в формальный стандарт ECMAScript. Вы уже можете использовать его в последних настольных версиях Chrome, Edge и Firefox, но нам придется немного подождать, пока эта функция не достигнет кросс-браузерной стабильности.

Взгляните на следующий пример, чтобы продемонстрировать его поведение:

// 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}`);

Предыдущий пример эквивалентен:

const var1 = undefined;
const var2 = "fallback value";

const result = (var1 !== null && var1 !== undefined) ?
    var1 :
    var2;
console.log(`Nullish coalescing results in: ${result}`);

Обратите внимание, что слияние нулевого значения не будет угрожать ложным значениям так, как|| оператор сделал (он проверяет только undefined или null values), поэтому следующий фрагмент будет действовать следующим образом:

// 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}`);


Для пользователей TypesScript, начиная с TypeScript 3.7, эта функция также доступна сейчас.

Остерегайтесь специфического для JavaScript определения ноль. Есть два определения "нет значения" в JavaScript. 1. Null: когда переменная имеет значение null, это означает, что в ней нет данных, но переменная уже определена в коде. как это:

var myEmptyValue = 1;
myEmptyValue = null;
if ( myEmptyValue === null ) { window.alert('it is null'); }
// alerts

в таком случае тип вашей переменной на самом деле Object. Попробуй это.

window.alert(typeof myEmptyValue); // prints Object
  1. Не определено: когда переменная не была определена ранее в коде, и, как и ожидалось, она не содержит никакого значения. как это:

    if ( myUndefinedValue === undefined ) { window.alert('it is undefined'); }
    // alerts
    

в таком случае тип вашей переменной "неопределенный".

обратите внимание, что если вы используете оператор сравнения преобразования типов (==), JavaScript будет действовать одинаково для обоих этих пустых значений. чтобы различать их, всегда используйте оператор сравнения со строгим типом (===).

В настоящее время нет поддержки, но процесс стандартизации JS работает над этим: https://github.com/tc39/proposal-optional-chaining

Прочитав ваше разъяснение, ответ @Ates Goral предоставляет информацию о том, как выполнить ту же операцию, которую вы выполняете в C# в JavaScript.

Ответ @Gumbo обеспечивает лучший способ проверить на ноль; Тем не менее, важно отметить разницу в == против === в JavaScript, особенно когда речь заходит о проверке undefined и / или null,

Здесь есть действительно хорошая статья о разнице в двух терминах. В принципе, понять, что если вы используете == вместо === JavaScript будет пытаться объединить сравниваемые значения и вернуть результат сравнения после этого слияния.

Обратите внимание, что React create-react-apptool-chain поддерживает объединение нулей, начиная с версии 3.3.0 (выпущенной 5.12.2019). Из примечаний к выпуску:

Необязательные операторы связывания и нулевые операторы объединения

Теперь мы поддерживаем необязательные операторы связывания и объединения с нулевым значением!

// 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

Это сказано, если вы используете create-react-app 3.3.0+ вы можете начать использовать оператор null-coalesce уже сегодня в своих приложениях React.

Слишком много разговоров, здесь два момента:

  1. Логическое ИЛИ

const foo = '' || 'строка по умолчанию';

console.log(foo); // вывод - 'строка по умолчанию'

  1. Нулевой оператор объединения

const foo = '' ?? 'строка по умолчанию';

console.log(foo); // вывод - пустая строка, т.е. ''

Оператор объединения с нулевым значением (??) - это логический оператор, который возвращает его правый операнд, когда его левый операнд имеет значение NULL или undefined, а в противном случае возвращает его левый операнд.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing_operator

Мы надеемся, что скоро он будет доступен в Javascript, поскольку с апреля 2020 года он находится в стадии предложения. Вы можете отслеживать статус здесь для совместимости и поддержки - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing_operator

Для людей, использующих Typescript, вы можете использовать нулевой оператор объединения из Typescript 3.7.

Из документов -

Вы можете подумать об этой функции - ?? оператор - как способ "вернуться" к значению по умолчанию при работе с null или undefined. Когда мы пишем код вроде

let x = foo ?? bar();

это новый способ сказать, что значение fooбудет использоваться, когда он "присутствует"; но когда этоnull или undefinedрассчитать bar() на свое место.

Необходимо поддерживать старый браузер и иметь иерархию объектов

body.head.eyes[0]  //body, head, eyes  may be null 

может использовать это,

(((body||{}) .head||{}) .eyes||[])[0] ||'left eye'

ECMAScript 2021 включает две новые функции:

  1. Нулевой оператор объединения (??) , который является логическим оператором, который возвращает свой правый операнд, когда его левый операнд либо равен нулю, либо не определен, и в противном случае возвращает свой левый операнд.

Подробнее о логическом нулевом назначении можно узнать здесь https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_nullish_assignment .

Подробнее об операторе объединения Nullish можно узнать здесь https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing_operator .

Теперь он имеет полную поддержку в последней версии основных браузеров, таких как Chrome, Edge, Firefox, Safari и т. Д. Вот сравнение между оператором null и оператором Nullish Coalescing.

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

Цепочка нескольких значений / несколько значений

  • «короткое замыкание» включено: не выполнять дальнейшую оценку, если одно из первых значений является допустимым.
  • это означает, что порядок имеет значение, самые левые значения имеют приоритет
      const value = first ?? second ?? third ?? "default";

Хорошо, правильный ответ

Он существует в JavaScript? Да, это так. НО. В настоящее время по состоянию на 06.02.2020 он находится на этапе 3 и пока поддерживается не везде. Перейдите по ссылке в URL-адресе ниже и перейдите к заголовкам "Технические характеристики" и "Совместимость с браузером", чтобы получить дополнительную информацию о том, где это находится.

Цитата из: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing_operator

Оператор объединения с нулевым значением (??) - это логический оператор, который возвращает его правый операнд, когда его левый операнд имеет значение NULL или undefined, и в противном случае возвращает его левый операнд.

В отличие от логического оператора OR (||), левый операнд возвращается, если это ложное значение, которое не является нулевым или неопределенным. Другими словами, если вы используете || чтобы предоставить какое-то значение по умолчанию для другой переменной foo, вы можете столкнуться с неожиданным поведением, если вы сочтете некоторые ложные значения пригодными для использования (например, '' или 0). См. Ниже дополнительные примеры.

Хотите примеры? Перейдите по опубликованной мной ссылке, там есть все.

Тем, кто использует Babel, необходимо обновить до последней версии, чтобы использовать нулевое объединение (??):

Babel 7.8.0 поддерживает новые функции ECMAScript 2020 по умолчанию: вам больше не нужно включать отдельные плагины для нулевого объединения (??), дополнительного связывания (?.) И динамического импорта () с помощью preset-env

С https://babeljs.io/blog/2020/01/11/7.8.0

Я пытался проверить, является ли ввод нулевым, а затем использовать значение соответственно. Это мой код.

      let valueToBeConsidered = !inputValue ? "trueCondition" : "falseCondition",

Таким образом, если inputValue равно null, тогда valueToBeConsidered = falseCondition, а если inputValue имеет значение, то valueToBeConsidered = trueCondition.

Другие вопросы по тегам