Использование нулевого объединения в операторах, тернарных и необязательных цепочках

JavaScript — один из самых популярных компьютерных языков всех времен, и одной из причин этого является интуитивно понятный синтаксис JavaScript. Это даже не самая лучшая часть, лучшая часть заключается в том, что в язык регулярно добавляется множество новых функций.
Сегодня мы увидим, как некоторые из этих новых функций помогают нам писать более интуитивно понятный код.
Нулевой оператор объединения (??)
Нулевой оператор объединения (??) — это логический оператор, который возвращает свой правый операнд, когда его левый операнд равен null или undefined, и в противном случае возвращает свой левый операнд.
false || '@sun_anshuman' // returns '@sun_anshuman'
false ?? '@sun_anshuman' // returns false
0 || '@sun_anshuman' // returns '@sun_anshuman'
null || '@sun_anshuman' // returns '@sun_anshuman'
null ?? '@sun_anshuman' // returns '@sun_anshuman'
undefined ?? '@sun_anshuman' // returns '@sun_anshuman'
Проблема с || заключается в том, что это логический оператор, поэтому он приводит левый операнд к логическому значению перед оценкой, поэтому и 0, и '' равны false.
Вариант использования на примере
Предположим, вы создаете игру, в которой минимальный балл равен 0, и вы считаете -1 недопустимым баллом.
Поэтому, прежде чем обновлять оценку пользователя, вы хотели бы убедиться, что для нее задано допустимое значение или определенная недействительная оценка.
// the server returns 0
let score = fetchScoreFromServer();
// we only want the score to be -1 only if the score
// is undefined or null because 0 is a valid value
const finalScore = score || -1;
// but this will give us the invalid value even if,
// the first operand (0) is a valid value, leading to a bug
Как это решить, спросите вы? (Я знаю, что ты это уже знаешь, ха-ха)
let score = fetchScoreFromServer(); // returns 0 again
const finalScore = score ?? -1;
// finalScore stays score (0 in this case),
// unless the server returned null or undefined
Логическое нулевое присваивание (??=)
Оператор логического нулевого присваивания (x ??= y) присваивает, только если x является нулевым (null или undefined).
let user = { name: "anshuman_bhardwaj" };
user.twitter_name ??= "@sun_anshuman"; // assigns '@sun_anshuman'
console.log(user); // {name: "anshuman_bhardwaj", twitter_name: "@sun_anshuman"}
По сути, это операция присваивания, основанная на операторе ??.
Вариант использования на примере
// the above example can be rewritten like this
let finalScore = fetchScoreFromServer(); // returns 0 again
finalScore ??= -1;
// keeps value of 0
Другим хорошим местом для использования ?? будет ссылка на свойства объекта и использование значений по умолчанию. В этом случае мы можем использовать логическое нулевое назначение ??=, чтобы задать значения по умолчанию для undefined свойств.
const user = { email: '[email protected]', company: '' }
// assign user.name to email username if it's undefined
user.name ??= email.split("@")[0]
// make company Canoo if company not available on user
user.company ??= 'Canoo'
// this time company stays empty string
в операторе
Оператор in возвращает значение true, если указанное свойство находится в указанном объекте или цепочке его прототипов.
const user = { email: '[email protected]' }
'email' in user // return true
'name' in user // return false
Вы помните время, когда вы использовали значения undefined, потому что указанный ключ отсутствовал в Object.
Стоит отметить, что
Если вы установите для свойства значение undefined, но не удалите его, оператор in вернет значение true для этого свойства.
Вариант использования на примере
Хорошим примером использования является запуск проверок работоспособности перед выполнением операций со свойствами объекта, чтобы избежать неопределенных проверок и ошибок.
// we have an user object
let user = { email: "[email protected]" };
// now we want to assign it a name if its not available
// checks if user has email
if ("email" in user) {
// checks if user has name
if (!("name" in user)) {
user["name"] = user.email.split("@")[0];
} else {
console.log("Welcome user: " + user.name);
}
} else {
console.error("User does not have required property: email");
}
Использование in в массиве проверяет, является ли данный индекс пустым слотом или нет.
const emptyList = new Array(5)
empties[2] // returns undefined
2 in empties // returns false
empties[2] = 'anshuman_bhardwaj'
2 in empties // returns true
Необязательная цепочка (?.)
Оператор ?. подобен оператору . оператора цепочки, за исключением того, что вместо того, чтобы вызывать ошибку, если ссылка (пустая или неопределенная), выражение сокращается с возвращаемым значением неопределенного.
let user = { name: 'anshuman' }
user.address.zipcode // TypeError
user.addess?.zipcode // returns undefined
Стоит отметить, что
- При использовании с вызовами функций возвращает значение undefined, если данная функция не существует.
- Необязательную цепочку нельзя использовать для необъявленного корневого объекта, но можно использовать с неопределенным корневым объектом.
Варианты использования на примерах
// user can be null or an Object containing email
const user = getUserFromDev()
// if we do this it will run fine when user is an Object
// but when user is null this will give a TypeError
console.log(user.email)
// we can fix this by using optional chaining
console.log(user?.email)
// logs the actual user email when user is an Object
// logs undefined if user is null but doesn't crash
Условный тернарный оператор (?)
Тернарный оператор проверяет, истинно ли указанное условие, если оно истинно, то возвращает первое выражение, иначе возвращает второе выражение.
x ? y : z означает, что если x истинно, вернуть y, иначе вернуть z.
let user = { age: 22 }
user['status'] = user.age > 18 ? 'adult' : 'minor'
// user.status is 'adult'
Этот оператор не специфичен для JavaScript, я впервые использовал его в C++.
Вариант использования на примере
let user = { email: "[email protected]" };
// lets consider this code, simple enough?
if ("email" in user) {
user["name"] = user.email.split("@")[0];
} else {
user["name"] = "Anonymous";
}
// we can make it even simpler by using ternary
user["name"] = "email" in user ? user.email.split("@")[0] : "Anonymous";
Использование тернарного кода является личным предпочтением, оно подходит для встроенных выражений, иначе все можно поставить как if-else
Бонус
Вот несколько примеров сочетания вышеперечисленных функций, давайте посмотрим, кто сможет ответить правильно в комментариях.
// consider the examples independent of each other
const user = { email: '[email protected]', lastName: undefined }
// 1
user["firstName"] = "email" in user
? user.email.split("_")[0]
: "Anonymous";
// 2
user["familyName"] ??= 'Bhardwaj'
// 3
console.log('lastName' in user)
// 4
console.log('' ?? '@sun_anshuman')
Узнать больше
Вы также можете посмотреть это видео на YouTube, где я объясняю эти примеры.
Вы также можете разветвить CodeSandBox, чтобы попробовать примеры.
Я надеюсь, что этот пост был полезен для вас. Если у вас есть какие-либо отзывы или вопросы, пожалуйста, не стесняйтесь задавать их в комментариях ниже. Я хотел бы услышать и работать над ними.
Для большего количества такого контента, пожалуйста, следуйте за мной
- Твиттер
- "YouTube"
- "Середина"
До следующего раза

Ресурсы
Первоначально опубликовано на https://theanshuman.dev 17 января 2022 г.
Больше контента на plainenglish.io. Подпишитесь на нашу бесплатную еженедельную рассылку новостей. Получите эксклюзивный доступ к возможностям написания и советам в нашем сообществе Discord.