Я прохожу курс ES6 Javascript: The Complete Developer Guide Stephen Grider
самостоятельно. Этот курс - мое первое знакомство с javascript. Он содержит интересное (для меня) упражнение по обнаружению сбалансированных скобок. Я написал функцию с ожидаемыми функциями, но я не использовал жирные стрелки. Я, вероятно, не использовал другие функции ECMAScript 6, которые мог бы использовать. Я хотел бы получить какие-либо предложения по улучшению моего кода.
function balancedParens(inputString){
const errMsg1 = 'ERROR: expression will NEVER be balanced';
const errMsg2 = 'ERROR: unbalanced!';
const successMsg = 'parens are balanced.';
const chars = inputString.split("");
let count = 0;
for ( let i = 0; i < chars.length; ++i ) {
if ( count < 0 ) { console.log(errMsg1); return false; }
if ( chars[i] === "(" ) { ++count; }
else if ( chars[i] === ")" ) { --count; }
}
if ( count < 0 ) { console.log(errMsg1); return false; }
else if ( count == 0 ) { console.log(successMsg); return true; }
else { console.log(errMsg2); return false; }
}
balancedParens("()()(i)"); //correctly returns true
balancedParens("()()())"); //correctly returns false
Моя функция обнаруживает парены, которые никогда не могут быть уравновешены, и выручает рано, что не было примером из курса. Я хочу сохранить эту функцию при рефакторинге и улучшении своего кода.
Курс настоятельно рекомендует не использовать циклы for, но я не мог придумать лучшего способа реализовать свои функции. И я не мог понять, как использование жирных стрелок улучшит код. Поэтому я с нетерпением жду предложений и отзывов.
Я думаю, что ваш код в порядке. Это просто и легко понять. Однако это определенно не то, что нынешние хипстеры javascript считают крутыми или что-то в этом роде.
К сожалению, без использования традиционной структуры цикла, такого как цикл for, вы не можете выйти рано, когда паренсы не могут быть сбалансированы. Так что, честно говоря, ваша функция, вероятно, более эффективна, чем то, что они ищут. Но, вообще говоря, хипстерам javascript на самом деле наплевать на эффективность кода.
Это может быть больше, что они ищут:
const balancedParens = inputString =>
// We don't need curly brackets here because we're doing everything
// on one "line" and just returning
inputString.split('')
// Reduce is the substitute for your for loop here.
// It iterates over each character and stores the return value in "sum"
// on each iteration
.reduce((sum, char) => {
if (char === '(') return sum + 1;
else if (char === ')') return sum - 1;
else return sum;
// This comparison makes the entire function return true if
// our reduce resulted in zero, otherwise false
}, 0) === 0;
const logResult = result =>
result ? console.log('parens are balanced.')
: console.log('ERROR: unbalanced!');
logResult(balancedParens('()()(i)'));
logResult(balancedParens('()()())'));
Если вы не знакомы с функцией Reduce в массиве, проверьте ее здесь: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce
Это функция высшего порядка (имеется в виду функция, которая принимает функцию в качестве одного из аргументов). Это общий случай использования жирных стрел просто потому, что обозначения в конечном итоге гораздо более кратки.
Примечание: я мог бы скептически относиться к любому курсу, который "настоятельно рекомендует против" для циклов. Но, возможно, они просто пытаются заставить вас использовать новые функции JS.
Я не уверен в контексте, но нет никаких оснований полагать, что циклы по своей природе плохие. Возможно, вы захотите знать о влиянии на производительность вложенности циклов, но классические циклы for используются достаточно часто, и нет никаких причин не использовать их.
Что касается функций со стрелками, в вашем случае преимущества могут заключаться в том, что ваш код более лаконичен и удобен для чтения. Функции со стрелками - это просто сокращенный способ написания функций. Чаще всего удобочитаемость важнее, чем небольшие улучшения производительности, которые вы можете получить или не получить, используя функции стрелок, потоки и функции функционального программирования, предоставляемые в ES6.
Для вашего случая было бы неплохо использовать некоторые функции стрелок, чтобы сделать ваш код более лаконичным. Таким образом, вы можете заменить цикл for путем потоковой передачи массива char и использования .forEach
.
Мое личное мнение таково, что функции стрелок работают лучше всего, когда вам не нужно привязывать это к текущему контексту функции. На данный момент это не имеет никакого смысла для вас, но функции стрелок не имеют своего собственного ключевого слова this, что означает, что значение этого будет вынесено за пределы лексической области действия функции arrow. Они хороши и для обратных вызовов (применимо то же правило, что и выше), также, когда вам нужно написать короткое выражение, оно выглядит аккуратно. Все зависит от вас, просто убедитесь, что вы знаете, как это ведет себя, и вы будете в порядке.
Функция Reduce может быть использована для перебора строки и возврата одного значения. уменьшить
Стрелочные функции используются для лексического определения этого. Функции стрелок
Обновление ES5 features- связать, позвонить и применить.
const errMsg1 = 'ERROR: expression will NEVER be balanced';
const errMsg2 = 'ERROR: unbalanced!';
const successMsg = 'parens are balanced.';
balancedParanthesis = (string) => {
return string.split("").reduce((count, char) => { //returns boolean expression
if(count < 0 ){return count;}
else if(char === '('){++count;}
else if(char === ')'){ --count;}
return count;
},0)
}
let count = balancedParanthesis("()()");
//let count = balancedParanthesis("((())");
//let count = balancedParanthesis(")((())");
if ( count < 0 ) { console.log(errMsg1); }
else if ( count == 0 ) { console.log(successMsg); }
else { console.log(errMsg2); }