2016-11-16 2 views
0

Я сегодня утром задал вопрос относительно ката, который я пытался решить. В этом вопросе (найдено здесь, если интересно Kata Question) Мне нужно было добавить оператор return к моей функции, чтобы избежать ошибки Value is not what was expected.Confused о `return` в javascript. Объяснение необходимо

Теперь у меня вторая итерация моего ката решения попробовать и здесь:

function isMerge(s, part1, part2) { 
    var pointer = 0 
    splitString = s.split(''); 
    splitString.forEach(function(character) { 
    if (part1.includes(character) || part2.includes(character)) { 
     pointer++; 
     return true; 
    } else { 
     return false; 
    } 
    }); 
} 

isMerge('codewars','cdw','oears') 

я все еще получаю Value is not what was expected ошибки при попытке выполнить код и на этот раз я запутался, почему, в частности, это происходит.

Для начала, взяты из руководства MDN

Инструкция возврата заканчивает выполнение функции и определяет значение, которое будет возвращено функцией вызывающей.

выражение Выражение для возврата. Если этот параметр опущен, вместо него возвращается undefined.

Посмотрите на моей if/else логики я указание return true и return false состояния в моем forEach цикле, чтобы увидеть, если все символы из part1 и part2 в строке. Я возвращаю что-то так, почему у меня есть Value is not what was expected?.

Прежде всего, по определению оператора return функция должна останавливаться, когда она достигает этого ключевого слова. Однако, когда я помещаю в логику console.log(character), я могу видеть на моей консоли, что все символы выводятся, поэтому функция не прерывается вообще, когда выполняется return true. Почему это?

В-третьих, я смущен, когда использовать ключевое слово return в целом. Рассмотрим эти примеры из документов MDN для ForEach.

Пример 1:

function logArrayElements(element, index, array) { 
    console.log('a[' + index + '] = ' + element); 
} 

// Notice that index 2 is skipped since there is no item at 
// that position in the array. 
[2, 5, , 9].forEach(logArrayElements); 
// logs: 
// a[0] = 2 
// a[1] = 5 
// a[3] = 9 

Пример 2:

function Counter() { 
    this.sum = 0; 
    this.count = 0; 
} 
Counter.prototype.add = function(array) { 
    array.forEach(function(entry) { 
    this.sum += entry; 
    ++this.count; 
    }, this); 
    // ^---- Note 
}; 

var obj = new Counter(); 
obj.add([2, 5, 9]); 
obj.count 
// 3 
obj.sum 
// 16 

Ни одно return заявление в этих примерах.

Теперь посмотрите на этот пример .every.

function isBigEnough(element, index, array) { 
    return element >= 10; 
} 

[12, 5, 8, 130, 44].every(isBigEnough); 

И, наконец, из моего предыдущего вопроса, мне нужно добавить второе return заявление, как это, чтобы избежать ошибок значения.

function isBigEnough(element, index, array) { 
    return element >= 10; 
} 

function whenToUseReturn(array) { 
    return array.every(isBigEnough); 
} 

whenToUseReturn([12, 5, 8, 130, 44]); 

Так ....... в заключении, для моей первоначальной функции, которая началась в этом, как я должен выйти из цикла, когда я достигаю false и вернуть его и также, когда все символы в строке , как мне вернуть «кумулятивный» true и избежать ошибки Value. Надеюсь, это имеет смысл, и я могу уточнить с помощью изменений, чтобы лучше проиллюстрировать мою мысль.

+4

Операция 'return' возвращает из обратного вызова, который вы передаете' forEach', * not * из 'isMerge'. 'isMerge' не содержит оператора' return', поэтому он возвращает 'undefined'. –

+0

И FWIW, * iff * операторы return внутри обратного вызова возвращаются из 'isMerge', он всегда будет возвращаться в первой итерации массива, так что это было бы не очень полезно в любом случае. –

ответ

1

Я возвращаю что-то так, почему это так, что у меня значение не то, что ожидалось ?.

return В оператор возвращает от обратного вызова вы передаете forEach, не от isMerge. Операторы return не пересекают границы функций. isMerge не содержит оператора возврата, поэтому он возвращает undefined. Если мы немного перепишем функцию, это может стать яснее:

function doSomething(part1, part2) { 
    return function(character) { 
    if (part1.includes(character) || part2.includes(character)) { 
     return true; 
    } else { 
     return false; 
    } 
    } 
} 

function isMerge(s, part1, part2) { 
    splitString = s.split(''); 
    splitString.forEach(doSomething(part1, part2)); 
} 

isMerge('codewars','cdw','oears') 

Это эквивалентно вашему коду. Как вы можете видеть, в isMerge нет return.

В этих примерах не приводится ни одного заявления о возвращении.

Там нет return заявления в forEach примерах, потому что forEachничего с возвращаемым значением обратного вызова не делать, так что нет никакого смысла в возвращении ничего.

forEach - это просто другой способ итерации по массиву, но он не дает значения, такого как reduce или every.

Как я должен выйти из цикла, когда я дошел до false и вернул его, а также, когда все символы находятся в строке, как мне вернуть «кумулятивный» true и избежать ошибки Value.

Вы не можете выйти из цикла forEach. Если вам нужно остановить итерацию раньше, вам нужно использовать обычный цикл for (for/in, for/of).

Чтобы вернуть и введите значение, вы можете использовать свое первоначальное решение, которое использует every.

1

Мой друг, поскольку вы решили пойти «обратный путь» с использованием .each и т. П., Вам следует рассмотреть возможность использования обратных вызовов, поскольку в этом случае вы ничего не можете вернуть. Если вы не хотите идти обратного пути, просто использовать стандартный JavaScript, например:

splitString.forEach(function(character) { 

Заменить

for(var i = 0 ; i < splitString.length; i++){ 

И теперь вы можете вернуться. Использование «each» для цикла массива просто ненужно и не позволяет вам вернуться.

+1

_Используя «каждый», чтобы закодировать массив, просто плохая_Что ??? – baao

+0

Его пример просто доказал это. – Eric

+0

Абсолютно правильно. В ES6 'forEach' мертв и не должен использоваться. Используйте 'for (let char of string)'. – georg

Смежные вопросы