предисловие
Говоря об этом, необязательный оператор цепочки (optional chaining) оба присоединяютсяbabelПакет существует уже давно, а автор до сих пор не использовал его на практике.Во-первых, у меня полусырое понимание этой фичи, а во-вторых, что у меня не выработалась такая привычка~
Вот список часто используемых сценариев, которые лучше использовать в проектной практике в следующий раз.
Введение в необязательный оператор цепочки
Так как JavaScript является динамическим языком, мы всегда стараемся использовать защитное программирование при доступе к свойствам объекта.
Например, мы хотим получить доступ к свойству объекта, но объект возвращается внутренним интерфейсом, который может бытьnull, в это время мы обычно пишем это при доступе к свойствамobj.key ,но еслиobj дляnull, то вы получите сообщение об ошибке от браузера в это время, как показано ниже 😂.
Такого рода операции на самом деле очень распространены в повседневном программировании, и мы обычно кодируем таким образом, чтобы избежать подобных ошибок.
obj && obj.name.Но хорошо, что атрибут является одним слоем, но в некоторых экстремальных сценариях ваш слой данных очень глубокий, например
obj.a.b.c.d.name.Перед необязательной цепочкой мы использовали некоторые сторонние библиотечные функции для решения этой проблемы.
- lodash.get
- Используйте деконструкцию ES6 (также необходимо очистить и писать слой по слою, глубокая деконструкция все еще громоздка)
- Внедрите safeGet самостоятельно или изучите метод get в you-dont-need-lodash ->источник кода
const get = (obj, path, defaultValue = undefined) => {
const travel = regexp =>
String.prototype.split
.call(path, regexp)
.filter(Boolean)
.reduce((res, key) => (res !== null && res !== undefined ? res[key] : res), obj);
const result = travel(/[,[\]]+?/) || travel(/[,[\].]+?/);
return result === undefined || result === obj ? defaultValue : result;
};
Как насчет необязательных цепочек?
Давайте посмотрим на каштан 🌰.
const obj = { a: { b: [{ name: 'obj' }] } }
// 原本的写法
console.log(obj && obj.a && obj.a.b.length && obj.a.b[0].name)
// 可选链写法
console.log(obj?.a?.b?.[0]?.name); // obj
console.log(obj?.b?.c?.d) // undefined
Это значительно упрощает суждение, но его можно использовать
Здесь если ?. объект суждения естьnullish(либо
undefined, либоnull) стоимость. Выражение будет сокращено (не выполнено позже), возвращаяundefined Если сотрудничатьНулевая операция слиянияиспользуй это~
const obj = { a : { name: 'obj'} }
obj?.a?.b ?? 'hello world' // hello world
Здесь тоже есть на что обратить вниманиеОставлен только нулевой оператор объединенияnullishКогда , вернет выражение справа.
И у нас было логическое или||действовать,Если левая часть ложна, возвращается выражение справа.
Как использовать в проекте
Node
Для Node.js встроенная поддержка доступна в версии 14.0.0 или выше.
Интерфейсный проект
можно использоватьПлагин Бабельиспытать.
Установить
yarn add @babel/plugin-proposal-optional-chaining --dev
использовать
{
"plugins": ["@babel/plugin-proposal-optional-chaining"]
}
Полное введение в официальный сайт Babel
в шаблоне Vue
Жаль, что я его пока не поддерживаю~ Посмотрите на большой.
основное использование
читать свойства объекта
const obj = { a: { name: 'obj' } }
obj?.a?.name // obj
Чтение свойств объекта, динамический ключ
const obj = { a: { name: 'obj' } }
obj?.a?.['name'] // obj
Доступ к индексу массива
const skills = ['CSS', 'HTML', 'JavaScript', 'Vue']
skills?.[3] // Vue
вызов функции
const obj = {
fun() {
console.log('hello world')
}
}
obj?.fun?.() // hello world
Расширенное использование
вместо тернарного оператора
foo ? foo.bar : defaultValue // before
foo?.bar ?? defaultValue // after
Упрощенная оценка регулярных выражений
// before
let match = "#C0FFEE".match(/#([A-Z0-9]+)/i)?.[1]
let hex = match && match[1]
// after
let hex = "#C0FFEE".match(/#([A-Z0-9]+)/i)?.[1]
проверка собственности
// before
if (element.prepend) element.prepend(otherElement);
// after
element?.prepend(otherElement)
избегать чрезмерного использования
Хотя у нас есть молоток🔨, мы не можем видеть все как гвоздь.
После принятия решения необходимо выполнить несколько операций.
// before
if (foo) {
something(foo.bar);
somethingElse(foo.baz);
andOneLastThing(foo.yolo);
}
// after
something(foo?.bar);
somethingElse(foo?.baz);
andOneLastThing(foo?.yolo);
Для рефакторинга кода здесь нам нужно будет оценить только один раз, нужно будет оценить три раза... И без добавления атрибута метод нужно будет оценить снова.
Так что вы не можете использовать его случайно, дорогой!
опустить суждение об уступке
// before
if (foo && foo.bar) {
foo.bar.baz = someValue;
}
// after
foo?.bar?.baz = someValue
Когда вы видите этот код, думаете ли вы, что это нормальная операция?
запустить его
Очевидно, нам бросилась в глаза ошибка запуска~
Так что, хотя необязательная цепочка хороша, ее не следует использовать без разбора!
использовать ловушку
Судейство строгого равенства
Сначала давайте посмотрим на кусок кода
if (foo?.bar === baz) {
// todo
}
Посмотрите на это, кажется, что нет никаких проблем?
из-за скрытого
BugОн должен соответствовать условиям для срабатывания (но некоторые друзья могут сказать, что это не так).Bug, но пасхалки у меня остались...)- когда
fooЕсли не указано, необязательное выражение цепочки вернетundefined - когда
bazЗначение переменнойundefinedкогда
Поздравляю, логику прогнали.Точно будут такие проблемы, когда суждения не равны.
Оценка нестрогого равенства
Сначала посмотрите код
if (foo?.bar !== SomeValue) {
// TODO
}
Как упоминалось выше, если необязательное выражение цепочки сокращено, оно вернетundefined, то, еслиsomeValueЕсли это другое значение, возможно, вы закопали пасхальное яйцо в своем собственном коде.
Напримерundefined !== 'string' ...
Эпилог
В этой статье рассказывается, что такое необязательная цепочка, а также базовый синтаксис и перечислены некоторые сценарии использования.Я думаю, вы должны были изучить это, если вы такие умные!
Не бойтесь столкнуться с глубоко вложенными объектами, выброшенными серверной частью в следующий раз~