javas встановити змінну, якщо вона не визначена


172

Я знаю, що я можу перевірити змінну javascript, а потім визначити її, якщо вона не визначена, але чи не існує способу сказати

var setVariable = localStorage.getItem ('значення') || 0;

здається набагато зрозумілішим способом, і я майже впевнений, що бачив це іншими мовами.


30
це не тест для "невизначених", це тест на "фальси"
Альнітак

3
Зауважте, що localStorage.getItem()викинутиме виняток, якщо користувач відключив файли cookie (принаймні, у Chrome), тому ви, можливо, захочете try...catch
зафіксувати

Відповіді:


304

Так, це можна зробити, але строго кажучи, це призначить значення за замовчуванням, якщо отримане значення є фальсі , на відміну від справді невизначеного . Було б , отже , не тільки відповідають , undefinedале і null, false, 0, NaN, "" (але НЕ "0" ).

Якщо ви хочете встановити значення за замовчуванням, лише якщо ця змінна є строго, undefinedтоді найбезпечнішим способом є написання:

var x = (typeof x === 'undefined') ? your_default_value : x;

У новіших браузерах насправді безпечно писати:

var x = (x === undefined) ? your_default_value : x;

але майте на увазі, що можна підривати це в старих браузерах, де було дозволено оголосити змінну, undefinedяка має визначене значення, внаслідок чого тест не вдасться.


3
Я здивований, що ця модель не входить до більшої кількості ліній JS.
joemaller

Чи є недолік використовувати var x = (x === undefined ? def_val : x);як трохи довший var x = (typeof x === 'undefined') ? def_val : x;. Чи відрізняється поведінка?
Марко Пашков

3
@marco у старих веб-переглядачах можна undefinedбуло переосмислити, що призведе до невдачі тесту на рівність.
Альнітак

@Alnitak, що є найкращим підходом до використання аналогічного синтаксису до того, який використовує ОП, і все-таки перевіряє, чи не визначено?
Іво Перейра

@IvoPereira Ви не можете використовувати ||підхід у строгому тесті для невизначених, ви повинні використовувати явний тест для undefinedумовного.
Альнітак

26

Відповідь ES6 2018 року :

return Object.is(x, undefined) ? y : x;

Якщо змінна x не визначена, поверніть змінну y ... інакше, якщо визначена змінна x, поверніть змінну x.


4
Наскільки я можу сказати, Object.isце не краще, ніж ===у цьому випадку. "Оператор === (а також оператор ==) розглядає значення чисел -0 та +0 як рівні і вважає Number.NaN не рівним NaN." ( developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… ) тут не має значення.
Тревор Діксон

5
Я не погоджуюсь. Знайте їх обох і використовуйте відповідне. Зокрема, використовувати, Object.isякщо можуть бути обидва операнди NaN.
Тревор Діксон

2
Якщо Object.is () працює у 100% випадків використання, а === працює у 98% випадків використання, чому б ви взагалі ризикували використовувати ===? Наприклад: console.log (+0 === -0); // виводить true, тоді як console.log (Object.is (+0, -0)); // виводить помилково - що краще? Чи мінус 0 такий же, як і позитивний 0? Це питання, яке ви повинні задати собі, але якщо ви використовуєте Object.is (), ви завжди знаєте відповідь. Вони не однакові, тому вихід помилкових є правильним і очікуваним результатом.
Стерлінг Борн

2
Конкретний контекст тут завжди порівнюється undefined. Так ===буде працювати 100% часу, а не лише 98%. Перевага в ===тому, що це легше читати, особливо на перший погляд, коротше і уникає зайвого виклику методу. Особисто я б користувався лише Object.is()тоді, коли цього вимагає ситуація, і я віддаю перевагу ===в усіх інших випадках.
blubberdiblub

1
Абсолютно; якщо ви досвідчений кодер. Якщо ви випадково не забудете знак рівності, і в такому разі налагодження, чому == не працює десь, - це я ніколи не бажаю жодному розробнику. Краще безпечніше, ніж вибачте, і завжди використовуйте Object.is (), тому причина була включена в специфікацію саме для того, щоб допомогти розробникам писати менше баггі-коду.
Стерлінг Борн

7

Мені потрібно було "встановити змінну, якщо не визначено" в декількох місцях. Я створив функцію, використовуючи @Alnitak відповідь. Сподіваємось, це комусь допомагає.

function setDefaultVal(value, defaultValue){
   return (value === undefined) ? defaultValue : value;
}  

Використання:

hasPoints = setDefaultVal(this.hasPoints, true);

6

Здається більш логічним перевірити typeofзамість undefined? Я припускаю, що ви очікуєте число під час встановлення var, 0коли не буде визначено:

var getVariable = localStorage.getItem('value');
var setVariable = (typeof getVariable == 'number') ? getVariable : 0;

У цьому випадку, якщо getVariableце не число (рядок, об'єкт, що завгодно), встановлюється setVariable0


5

Відповідь ES2020

За допомогою оператора Nullish Coalescing ви можете встановити значення за замовчуванням, якщо воно valueє нульовим або невизначеним.

const setVariable = localStorage.getItem('value') ?? 0;

Однак слід пам’ятати, що оператор зведення нуля не повертає значення за замовчуванням для інших типів фальшивого значення, таких як 0і ''.

Зверніть увагу, що підтримка браузера для оператора обмежена. За даними каніуси підтримується лише 48,34% браузерів (станом на квітень 2020 року). Підтримка Node.js додана у версії 14 .


2

Якщо ви фанат FP ( функціонального програмування ), Ramda має чітку функцію помічника для цього, що називається defaultTo :

використання:

const result = defaultTo(30)(value)

Це корисніше при роботі з undefinedбулевими значеннями:

const result2 = defaultTo(false)(dashboard.someValue)


1
це саме так const result = value || 30;, за винятком використання функції "між" та +1000 байтів lib
Аделін

1
@Adelin не відповідає дійсності, він також обробляє помилку для булевих типів. Якщо ви вже користуєтеся цією лібкою (як і я), то це дуже корисно і коротко
Damian Green

1

var setVariable = (typeof localStorage.getItem('value') !== 'undefined' && localStorage.getItem('value')) || 0;


Не буде також призначати 0, якщо localStorage.getItem('value'))повернетьсяfalse
Карл Адлер

1

Сьогодні я потрапив у цей сценарій, де я не хотів, щоб нуль було перезаписано на кілька значень. У нас є файл з деякими загальними корисними методами для подібних сценаріїв. Ось що я додав, щоб обробляти сценарій та бути гнучким.

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

Потім його можна викликати, якщо останні два параметри є необов'язковими, якщо я хочу встановити лише невизначені значення або також замінити нульові або 0 значення. Ось приклад виклику до нього, який встановить ідентифікатор до -1, якщо ідентифікатор не визначений або недійсний, але не буде замінено значення 0.

data.ID = Util.getIfNotSet(data.ID, -1, true);

1

У наші дні ви насправді можете зробити свій підхід із JS:

// Your variable is null
// or '', 0, false, undefined
let x = null;

// Set default value
x = x || 'default value';

console.log(x); // default value

Тож ваш приклад БУДЕ працювати:

const setVariable = localStorage.getItem('value') || 0;

0

Працює, навіть якщо значенням за замовчуванням є булеве значення:

var setVariable = ( (b = 0) => b )( localStorage.getItem('value') );

0

Мені здається, що для поточних реалізацій JavaScript,

var [result='default']=[possiblyUndefinedValue]

це хороший спосіб зробити це (використовуючи деконструкцію об'єкта).


0

Логічне нульове призначення, рішення ES2020 +

Нові оператори в даний час додаються в браузерах, ??=, ||=, і &&=. Цей пост буде присвячений ??=.

Це перевіряє, чи ліва сторона не визначена чи нульова, коротке замикання якщо вже визначено. Якщо ні, праворуч присвоюється лівій змінній.

Порівняння методів

// Using ??=
name ??= "Dave"

// Previously, ES2020
name = name ?? "Dave"

// Before that (not equivalent, but commonly used)
name = name || "Dave" // name ||= "Dave"

Основні приклади

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

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

// Equivalent to
a = a ?? true

Приклади об'єктів / масивів

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 р. - .03%

?? = Документація Mozilla

|| = Документація Mozilla

&& = Документація Mozilla


Дійсно скопіювати цю відповідь на два інші запитання ( Замініть значення, якщо в JavaScript не вказано нульове значення та чи існує оператор “null coalescing” в JavaScript? )? Чи не було б краще VTC як дублікат або посилання на пов'язані питання в коментарях?
користувач4642212

Усі питання дещо різні; як такі так є відповіді. Приклади послідовні для покращення вбудованого контексту з першого погляду. Можливо, міг би зв’язатися для більш детальної інформації, але зажадав би додатковий
скачок,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.