Есть 2 разных вопроса, которые необходимо рассмотреть более подробно.Давайте сосредоточимся на первом случае, когда основной проблемой является то, что вы определяете функцию стрелки ES6 и вызываете ее позже без параметров:
i => console.log(i)
при преобразовании в анонимную функцию ES5:
function(i){ console.log(i) }
Таким образом, в i => console.log(i)
имеется короткое определение ES6 для анонимной функции (также известной как обозначение функции стрелки ES6 ), которая принимает параметр i
.
Конечным результатом является то, что console.log(i)
пытается напечатать i
, то есть undefined
, поскольку он не передается этой функции стрелки во время выполнения.
Вы снова нажимаете определение функции, которую затем выполняете без передачи в нее параметра, который необходим для его вывода на консоль.
var fs = [];
for(var i=0; i<10; i++){
// You are pushing to the array the below anonymous function definition
fs.push(
// You are creating an anonymous function which accepts i and console.logs it
i => console.log(i)
);
}
fs.forEach(
// You are calling the "pushed" above function definition with NO parameter i
f => f()
);
Теперь давайте рассмотрим, почему и как работает 2-й пример кода и как var/let
играет большую роль в выводе консоли:
let fs = []
// You define i in the for-loop block score
for(var i=0; i<10; i++){
fs.push(
// You push an annonymous function definition wich has a reference of i in the same block scope
// However i is already here 10 since the loop is already done and it takes the last value of i
function(){ console.log(i) }
);
}
fs.forEach(
// You call f which has a reference inside to the i from the for loop
f => f()
);
Так что в этом случае i
при использовании var i
i
, поскольку он не сохраняет свою область видимости лексического блока, обновляется до 10
до того, какconsole.log вызывается.
Давайте попробуем это сейчас с let
:
let fs = []
// You define i via LET in the for-loop block score
for(let i=0; i<10; i++){
fs.push(
// You push an annonymous function definition wich has a reference of i in the same block scope
// i retains its lexical scope in for loops
function(){ console.log(i) }
);
}
fs.forEach(
// You call f which has a reference inside to the i from the for loop
f => f()
);
Немного больше о let:
let позволяет объявлять переменные, которые ограничены в области действия block , выражение или выражение , в котором оно используется.Это в отличие от ключевое слово var , которое определяет переменную глобально или локально для всей функции независимо от области видимости блока.