Как работает это абстрактное повторение? - PullRequest
2 голосов
/ 08 октября 2019

Я читаю кое-что из Javascript, так как мечтаю стать хорошим JS-разработчиком. Я вроде знаю, как использовать основы для полного удовлетворения моих потребностей в PHP, но есть некоторые сомнения.

Я видел несколько примеров и получил это:

function repeat(n, action) {
   for (let i = 0; i < n; i++) {
      action(i);
   }
}

let labels = [];

repeat(5, i => {
   labels.push(`Unit ${i + 1}`);
});

console.log(labels);

Итак, я могу использовать его для повторения некоторых основных функций, если это необходимо. Понял, но в другом случае я мог бы использовать ту же функцию с другим подходом.

Почему переменная i становится счетчиком / итератором, если я предполагаю передать функцию?

Я использовал его раньше всех времен, но до сих пор не знаю, как он работает, поэтому я не могу использовать его, когда это действительно необходимо.

Ответы [ 5 ]

5 голосов
/ 08 октября 2019

i не становится итератором. В коде вы используете сокращенную запись es6 для описания функции. i является единственным аргументом функции.

i => {
   labels.push(`Unit ${i + 1}`);
});

- это то же самое, что и

function(i){
  labels.push(`Unit ${i + 1}`);
} 

. См. Больше в этой ссылке на сокращенную запись

Редактировать: Чтобы ответить на ваш комментарий «Что добавляет его», вы должны более внимательно посмотреть на функцию repeat(n, action). Вас также может сбить с толку то, что i используется в обоих случаях, поэтому я перепишу эту функцию, чтобы помочь вам понять. Эта функция использует цикл for для итерации от 0 до n

for (let idx = 0; idx < n; idx++) {
   action(idx);
}

и вызывает действие с текущим для индекса цикла idx. Например,

Iteration 0: action(0) -> labels.push(`Unit ${0 + 1}`);
Iteration 1: action(1) -> labels.push(`Unit ${1 + 1}`);
Iteration 2: action(2) -> labels.push(`Unit ${2 + 1}`);
Iteration 3: action(3) -> labels.push(`Unit ${3 + 1}`);
Iteration 4: action(4) -> labels.push(`Unit ${4 + 1}`);

Обратите внимание, что объявление repeat для i является локальным по отношению к телу функции, так же как i в i => { labels.push( Unit $ {i+ 1} ); } локально для своего тела функции. Эти два значения i не ссылаются на одно и то же значение в памяти и могут быть переименованы, как я сделал в своем объяснении

2 голосов
/ 08 октября 2019

Немного сбивает с толку то, что вы используете i в качестве переменной в цикле for, а также в качестве параметра вашей функции стрелки. Если изменить параметр функции на x и увидеть, что он все еще работает, это может привести к лучшему пониманию областей действия переменных и облегчить объяснение:

repeat(5, x => {
   labels.push(`Unit ${x + 1}`);
});

Вы передаете функцию стрелки в repeat() функция. Внутри функции повтора цикл for увеличивает i на каждой итерации, в данном случае с 0 до 4, и каждый раз вызывает функцию стрелки, которую вы передали в качестве параметра action. Параметр x этой функции примет значение i, поскольку вы передаете его в качестве первого аргумента при вызове ссылки action (то есть функции стрелки).

2 голосов
/ 08 октября 2019

Это оригинальная функция

repeat(5, i => {
   labels.push(`Unit ${i + 1}`);
});

, которую можно записать как

repeat(5, function (i) {
    labels.push(`Unit ${i + 1}`);
});

Сделать анонимную функцию именованной, например,

var action = function(i){
  labels.push(`Unit ${i + 1}`);
} 

Затем repeat вызов становится, repeat(5, action); // действие - ссылка на функцию

Теперь мы можем изменить определение функции следующим образом, удалив ссылку на функцию action

function repeat(n) {
   for (let i = 0; i < n; i++) {
     action(i);
   }
}
var action = function(i){
  labels.push(`Unit ${i + 1}`);
} 

Это может быть

function repeat(n) {
   for (let i = 0; i < n; i++) {
     labels.push(`Unit ${i + 1}`);
   }
}

Результат будет ["Unit 1", "Unit 2", "Unit 3", "Unit 4", "Unit 5"] в консоли.

2 голосов
/ 08 октября 2019

В функции repeat вы передаете индекс forloop обратному вызову

function repeat(n, action) {
   for (let i = 0; i < n; i++) {
      action(i); // here you are passing index to callback
   }
}

и получаете индекс в виде параметров

repeat(5, i => { // Here you will get params that is passed by repeat function
   labels.push(`Unit ${i + 1}`);
});

Надеюсь, это поможет

0 голосов
/ 08 октября 2019

repeat функция получает обратный вызов, и каждая итерация передает текущему значению обратного вызова i

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...