Необязательная цепочка в JavaScript
Я очень много программировал в Swift. Сегодня я работал над JavaScipt, когда у меня возник вопрос:
Есть ли что-то похожее на необязательную цепочку в JavaScript? Способ предотвращения undefined is not an object
без каких-либо переменных?
Пример:
function test(){
if(new Date() % 2){
return {value: function(){/*code*/}};
}
}
test().value();
не удастся выполнить половину времени, потому что иногда test
возвращает undefined.
Единственное решение, о котором я могу думать, это функция:
function oc(object, key){
if(object){
return object[key]();
}
}
oc(test(), 'value');
Я хотел бы сделать что-то вроде:
test()?.value()
Часть после вопросительного знака выполняется только в том случае, если test
возвратил объект.
Но это не очень похоже. Есть что-то лучше? Волшебное сочетание операторов?
Изменить Я знаю, что могу переписать test
, чтобы вернуть что-то. Но мне интересно, есть ли что-то вроде дополнительной цепочки. Меня не интересует конкретное решение вышеприведенного примера. То, что я также могу использовать, если не имеет никакого контроля над функцией, возвращающей undefined.
Ответы
Ответ 1
В простом JavaScript вам нужно выполнить проверку типов или структурировать свой код, чтобы вы знали, что объект будет существовать.
CoffeeScript, язык, который скомпилирован с использованием JavaScript, предоставляет экзистенциальный оператор ?.
для безопасной цепочки, если вы хотите рассмотреть предварительно обработанный язык.
Здесь еще обсуждается о том, почему вы не можете воспроизвести это поведение в JS.
Существует также обсуждение на форумах ESDiscuss о добавлении экзистенциального оператора в будущую версию JavaScript. Это не очень далеко, хотя, конечно, нигде не приближается к практическому использованию. Больше идеи на данный момент.
Ответ 2
В настоящее время это предложение уровня 3, ход выполнения которого можно посмотреть здесь:
https://github.com/tc39/proposal-optional-chaining
Вы можете использовать плагин Babel сегодня:
https://www.npmjs.com/package/babel-plugin-transform-optional-chaining
Необязательный оператор цепочки пишется ?.. Может отображаться в трех позициях:
obj?.prop // optional static property access
obj?.[expr] // optional dynamic property access
func?.(...args) // optional function or method call
Примечание:
Чтобы позволить foo?.3: 0 быть проанализированным как foo?.3: 0 (как требуется для обратной совместимости), на уровне лексической грамматики добавлена простая "заглядывание", так что последовательность символов?. в этой ситуации не интерпретируется как один токен (за символом?. не должно быть сразу после десятичной цифры).
Также стоит проверить:
https://github.com/tc39/proposal-nullish-coalescing
https://github.com/babel/babel/tree/master/packages/babel-plugin-proposal-nullish-coalescing-operator
Ответ 3
Вы можете использовать
test() && test().value();
или
var testResult = test();
testResult && testResult.value();
Если вы спросите меня, это больше похоже на дополнительную цепочку Swift.
Ответ 4
Как насчет возврата функции noop, которая ничего не делает, когда условие не выполняется?
function test(){
if(new Date() % 2){
return {value: function(){/*code*/}};
}
return {value: function(){ /* just return a type consistent with the function above */ }
}
Ответ 5
Вы всегда можете return this;
, если test является объектным методом.
Но почему вы хотите предотвратить такие ошибки, создавая макетные функции?