Вам, по крайней мере, нужно будет отредактировать / etc / fstab, чтобы изменить ext4 на btrfs, изменить UUID (спасибо Riccardo за напоминание мне!) и, возможно, добавить или изменить параметры монтирования (и убедитесь, что он скопированы в initramfs тоже ...). Кроме того, необходимо внести изменения, необходимые для добавления раздела / boot.
Кроме того, помните, что btrfs все еще очень новый; более вероятно, что у него все еще много ошибок. Убедитесь, что вы не размещаете важные данные, если у вас нет резервных копий ...
Благодаря тому, что ES6 теперь широко поддерживается, лучший ответ на этот вопрос изменился. ES6 предоставляет ключевые слова let и const для этого точного обстоятельства. Вместо того, чтобы возиться с закрытием, мы можем просто использовать let для установки переменной области цикла таким образом:
var funcs = [];
for (let i = 0; i < 3; i++) {
funcs[i] = function() {
console.log("My value: " + i);
};
}
val затем укажет на объект, специфичный для этого конкретного поворота цикл, и вернет правильное значение без дополнительной записи закрытия. Это значительно упрощает эту проблему.
const аналогично let с дополнительным ограничением на то, что имя переменной не может отскочить к новой ссылке после первоначального присваивания.
Поддержка браузера теперь предназначена для тех, кто ориентирован на последние версии браузеров. const / let в настоящее время поддерживается в последних версиях Firefox, Safari, Edge и Chrome. Он также поддерживается в узле, и вы можете использовать его в любом месте, используя инструменты построения, такие как Babel. Здесь вы можете увидеть рабочий пример: http://jsfiddle.net/ben336/rbU4t/2/
Документы здесь:
const letОстерегайтесь, хотя IE9-IE11 и Edge до Edge 14 поддерживают let, но получают вышеизложенное (они не создают новый i каждый раз, поэтому все вышеперечисленные функции будут записывать 3, как если бы мы использовали var). Edge 14, наконец, все исправляет.
<script>
var funcs = [];
for (var i = 0; i < 3; i++) {
funcs[i] = function () {
debugger;
console.log("My value: " + i);
};
}
console.log(funcs);
</script>
Теперь откройте окно консоли Chrome, нажав F12 и обновите страницу. Расходуйте каждые 3 функции внутри массива. Вы увидите свойство, называемое [[Scopes]]. Разместите это. Вы увидите один объект массива с именем "Global", разверните его. Вы найдете свойство 'i', объявленное в объекте, имеющем значение 3.
chrome console window
Когда вы объявляете переменную с помощью 'var' вне функции, она становится глобальной переменной (вы можете проверить, набрав i или window.i в окне консоли. Он вернет 3 ). Анонимная функция, которую вы объявили, не будет вызывать и проверять значение внутри функции, если вы не вызываете функции. Когда вы вызываете функцию, console.log("My value: " + i) принимает значение из своего объекта Global и отображает результат.Теперь замените 'var' на 'let'
<script>
var funcs = [];
for (let i = 0; i < 3; i++) {
funcs[i] = function () {
debugger;
console.log("My value: " + i);
};
}
console.log(funcs);
</script>
Выполните то же самое, перейдите к областей. Теперь вы увидите два объекта "Block" и "Global". Теперь разворачиваем объект Block, вы увидите там 'i', и странно, что для каждой функции значение if i отличается (0, 1, 2).
[!d10]
Заключение:
Когда вы объявляете переменную, используя 'let' даже вне функции, но внутри цикла, эта переменная будет не будет глобальной переменной, она станет переменной уровня Block, которая доступна только для одной и той же функции. Именно поэтому мы получаем значение i для каждой функции при вызове функций.
Для более подробной информации о том, как работает более близко, пройдите через удивительный видеоурок [!d10]
Вот еще одна вариация в технике, подобная Bjorn's (apphacker), которая позволяет вам назначать значение переменной внутри функции, а не передавать ее как параметр, который иногда может быть более ясным:
for (var i = 0; i < 3; i++) {
funcs[i] = (function() {
var index = i;
return function() {
console.log("My value: " + index);
}
})();
}
] Обратите внимание, что любой метод, который вы используете, переменная index становится своего рода статической переменной, связанной с возвращенной копией внутренней функции. I.e., изменения его значения сохраняются между вызовами. Это может быть очень удобно.
После прочтения различных решений я хотел бы добавить, что причина, по которой эти решения работают, заключается в том, чтобы опираться на концепцию цепочки областей видимости. Это способ, которым JavaScript разрешает переменную во время выполнения.
Каждое определение функции формирует область, состоящую из всех локальных переменных, объявленных var и ее arguments. Если у нас есть внутренняя функция, определенная внутри другой (внешней) функции, это образует цепочку и будет использоваться во время выполнения. Когда функция выполняется, среда выполнения оценивает переменные путем поиска в цепочке областей видимости. Если переменная может быть найдена в определенной точке цепочки, она перестанет ее искать и использовать, иначе она будет продолжаться до тех пор, пока глобальная область не достигнет того, что принадлежит window.В исходном коде:
funcs = {};
for (var i = 0; i < 3; i++) {
funcs[i] = function inner() { // function inner's scope contains nothing
console.log("My value: " + i);
};
}
console.log(window.i) // test value 'i', print 3
Когда выполняется funcs, цепочка области видимости будет function inner -> global. Поскольку переменную i невозможно найти в function inner (ни объявлено с использованием var, ни передано как аргументы), она продолжает поиск, пока значение i не будет найдено в глобальной области видимости window.i .
Обернув его во внешнюю функцию, либо явно определите вспомогательную функцию, как harto, либо используйте анонимную функцию, такую как Bjorn:
funcs = {};
function outer(i) { // function outer's scope contains 'i'
return function inner() { // function inner, closure created
console.log("My value: " + i);
};
}
for (var i = 0; i < 3; i++) {
funcs[i] = outer(i);
}
console.log(window.i) // print 3 still
Когда выполняется funcs теперь цепочка областей видимости будет function inner -> function outer. На этот раз i можно найти в области внешней функции, которая выполняется 3 раза в цикле for, каждый раз имеет значение i правильно. Он не будет использовать значение window.i, если внутреннее исполнение выполнено.
Более подробная информация может быть найдена harto В нее входит общая ошибка при создании замыкания в цикле, как то, что мы имеем здесь, а также почему мы нуждаемся в закрытии и рассмотрении эффективности.
Функции JavaScript «закрывают» область, к которой они имеют доступ после объявления, и сохраняют доступ к этой области, даже если переменные в этой области меняются.
var funcs = []
for (var i = 0; i < 3; i += 1) {
funcs[i] = function () {
console.log(i)
}
}
for (var k = 0; k < 3; k += 1) {
funcs[k]()
}
Каждый функция в массиве выше закрывается над глобальной областью (глобальная, просто потому, что это область видимости, в которой они объявлены).
В дальнейшем эти функции вызывают регистрацию самого последнего значения i в глобальный охват. Это волшебство и разочарование в закрытии.
«Функции JavaScript закрываются по области, в которой они объявлены, и сохраняют доступ к этой области, даже если переменные значения внутри этой области изменяются».
Использование let вместо var решает это, создавая новую область каждый раз, когда цикл for запускается, создавая выделенную область для каждой функции, чтобы закрыть ее. Различные другие методы делают то же самое с дополнительными функциями.
var funcs = []
for (var i = 0; i < 3; i += 1) {
funcs[i] = function () {
console.log(i)
}
}
for (var k = 0; k < 3; k += 1) {
funcs[k]()
}
(let делает переменные областью с областью действия, а не функцией. Блоки обозначаются фигурными фигурными скобками, но в случае цикла for переменная инициализации i в нашем случае считается объявленной в фигурных скобках.)
Вот простое решение, которое использует forEach (работает в IE9):
var funcs = {};
[0,1,2].forEach(function(i) { // let's create 3 functions
funcs[i] = function() { // and store them in funcs
console.log("My value: " + i); // each should log its value.
};
})
for (var j = 0; j < 3; j++) {
funcs[j](); // and now let's run each one to see
}
Отпечатки:
My value: 0
My value: 1
My value: 2
Что вам нужно понять, так это объем переменных в javascript, основанный на функции. Это важная разница, чем сказать c #, где у вас есть область блока, и просто копирование переменной в одну из них будет работать.
Обертывание ее в функции, которая оценивает возврат функции, как ответ афкакера, сделает трюк, так как переменная теперь имеет область видимости функции.
Вместо var используется ключевое слово let, которое позволит использовать правило области блока. В этом случае определение переменной внутри for сделает трюк. Тем не менее, ключевое слово let не является практическим решением из-за совместимости.
var funcs = {};
for (var i = 0; i < 3; i++) {
let index = i; //add this
funcs[i] = function() {
console.log("My value: " + index); //change to the copy
};
}
for (var j = 0; j < 3; j++) {
funcs[j]();
}
Еще один способ, который еще не упоминался, - использование Function.prototype.bind
var funcs = {};
for (var i = 0; i < 3; i++) {
funcs[i] = function(x) {
console.log('My value: ' + x);
}.bind(this, i);
}
for (var j = 0; j < 3; j++) {
funcs[j]();
}
UPDATE
Как указано @squint и @mekdev, вы получаете лучшую производительность, сначала создавая функцию за пределами цикла, а затем привязывая результаты в цикле.
var funcs = {};
for (var i = 0; i < 3; i++) {
funcs[i] = function(x) {
console.log('My value: ' + x);
}.bind(this, i);
}
for (var j = 0; j < 3; j++) {
funcs[j]();
}
Самое простое решение:
Вместо использования:
var funcs = [];
for(var i =0; i<3; i++){
funcs[i] = function(){
alert(i);
}
}
for(var j =0; j<3; j++){
funcs[j]();
}
, который предупреждает «2», в 3 раза. Это связано с тем, что анонимные функции, созданные в цикле for, имеют одно и то же закрытие, а в этом закрытии значение i одинаково. Используйте это, чтобы предотвратить совместное закрытие:
var funcs = [];
for(var new_i =0; new_i<3; new_i++){
(function(i){
funcs[i] = function(){
alert(i);
}
})(new_i);
}
for(var j =0; j<3; j++){
funcs[j]();
}
Идея этого заключается в том, что инкапсуляция всего тела цикла for с помощью выражения IIFE (выражение с выражением немедленного вызова) и передача new_i в качестве параметра и захватив его как i. Поскольку анонимная функция выполняется немедленно, значение i отличается для каждой функции, определенной внутри анонимной функции.
Это решение, похоже, соответствует любой такой проблеме, поскольку оно потребует минимальных изменений в исходном коде, страдающем из этого вопроса. Фактически, это по дизайну, это не должно быть проблемой вообще!
Это описывает распространенную ошибку с использованием замыканий в JavaScript.
. Рассмотрим:
function makeCounter()
{
var obj = {counter: 0};
return {
inc: function(){obj.counter ++;},
get: function(){return obj.counter;}
};
}
counter1 = makeCounter();
counter2 = makeCounter();
counter1.inc();
alert(counter1.get()); // returns 1
alert(counter2.get()); // returns 0
За каждый раз makeCounter, {counter: 0} приводит к созданию нового объекта. Кроме того, создается новая копия obj для ссылки на новый объект. Таким образом, counter1 и counter2 не зависят друг от друга.
Использование замыкания в цикле является сложным.
Рассмотрим:
var counters = [];
function makeCounters(num)
{
for (var i = 0; i < num; i++)
{
var obj = {counter: 0};
counters[i] = {
inc: function(){obj.counter++;},
get: function(){return obj.counter;}
};
}
}
makeCounters(2);
counters[0].inc();
alert(counters[0].get()); // returns 1
alert(counters[1].get()); // returns 1
Обратите внимание, что counters[0] и counters[1] не являются независимыми. Фактически, они работают на одном и том же obj!
Это связано с тем, что есть только одна копия obj, разделенная на все итерации цикла, возможно, по соображениям производительности. Несмотря на то, что {counter: 0} создает новый объект на каждой итерации, одна и та же копия obj будет просто обновляться с ссылкой на самый новый объект.
Решение состоит в использовании другой вспомогательной функции:
function makeHelper(obj)
{
return {
inc: function(){obj.counter++;},
get: function(){return obj.counter;}
};
}
function makeCounters(num)
{
for (var i = 0; i < num; i++)
{
var obj = {counter: 0};
counters[i] = makeHelper(obj);
}
}
Это работает, потому что локальные переменные в области функции напрямую, а также переменные аргументов функции выделяются новыми экземплярами при записи.
Подробное обсуждение см. в примерах ошибок JavaScript и использование
COUNTER PRIMITIVE
Давайте определим функции обратного вызова следующим образом:
// ****************************
// COUNTER BEING A PRIMITIVE
// ****************************
function test1() {
for (var i=0; i<2; i++) {
setTimeout(function() {
console.log(i);
});
}
}
test1();
// 2
// 2
По завершении таймаута он будет печатать 2 для обоих. Это связано с тем, что функция обратного вызова обращается к значению на основе лексической области, где была определена функция.
Чтобы передать и сохранить значение при определении обратного вызова, мы можем создать лексическую область ! d4], чтобы сохранить значение до вызова обратного вызова. Это можно сделать следующим образом:
function test2() {
function sendRequest(i) {
setTimeout(function() {
console.log(i);
});
}
for (var i = 0; i < 2; i++) {
sendRequest(i);
}
}
test2();
// 1
// 2
Теперь в этом особенность: «Примитивы передаются по значению и копируются. Таким образом, когда ограничение определено, они сохраняют значение из предыдущего цикла».
COUNTER PRIMITIVE
Так как закрытие имеет доступ к родительским переменным функции посредством ссылки, этот подход будет отличаться от того, который используется для примитивов.
// ****************************
// COUNTER BEING AN OBJECT
// ****************************
function test3() {
var index = { i: 0 };
for (index.i=0; index.i<2; index.i++) {
setTimeout(function() {
console.log('test3: ' + index.i);
});
}
}
test3();
// 2
// 2
Таким образом, даже если для переменной, передаваемой как объект, создается замыкание, значение индекса цикла не будет сохранено. Это означает, что значения объекта не копируются, а к ним обращаются через ссылку.
function test4() {
var index = { i: 0 };
function sendRequest(index, i) {
setTimeout(function() {
console.log('index: ' + index);
console.log('i: ' + i);
console.log(index[i]);
});
}
for (index.i=0; index.i<2; index.i++) {
sendRequest(index, index.i);
}
}
test4();
// index: { i: 2}
// 0
// undefined
// index: { i: 2}
// 1
// undefined
Использование выражения с мгновенной вызывной функцией - простейший и наиболее читаемый способ заключить индексную переменную:
for (var i = 0; i < 3; i++) {
(function(index) {
console.log('iterator: ' + index);
//now you can also loop an ajax call here
//without losing track of the iterator value: $.ajax({});
})(i);
}
Это отправляет итератору i в анонимную функцию, которую мы определяем как index. Это создает замыкание, в котором переменная i сохраняется для последующего использования в любых асинхронных функциях внутри IIFE.
И еще одно решение: вместо создания другого цикла просто привяжите функцию this к функции возврата.
var funcs = [];
function createFunc(i) {
return function() {
console.log('My value: ' + i); //log value of i.
}.call(this);
}
for (var i = 1; i <= 5; i++) { //5 functions
funcs[i] = createFunc(i); // call createFunc() i=5 times
}
Связывая это, решает проблему как хорошо.
Я предпочитаю использовать функцию forEach, у которой есть собственное закрытие с созданием псевдодиапазона:
var funcs = [];
new Array(3).fill(0).forEach(function (_, i) { // creating a range
funcs[i] = function() {
// now i is safely incapsulated
console.log("My value: " + i);
};
});
for (var j = 0; j < 3; j++) {
funcs[j](); // 0, 1, 2
}
Это выглядит более уродливым, чем диапазоны на других языках, но IMHO менее чудовищным, чем другие решения.
Вы можете использовать декларативный модуль для списков данных, таких как query-js (*). В этих ситуациях я лично нахожу декларативный подход менее неожиданным
var funcs = Query.range(0,3).each(function(i){
return function() {
console.log("My value: " + i);
};
});
. Затем вы можете использовать свой второй цикл и получить ожидаемый результат, или вы могли бы сделать
funcs.iterate(function(f){ f(); });
(*) Я являюсь автором запросов-js и поэтому склонен к его использованию, поэтому не принимайте мои слова в качестве рекомендации для указанной библиотеки только для декларативного подхода:)
Этот вопрос действительно показывает историю JavaScript! Теперь мы можем избежать блочного охвата функциями стрелок и обрабатывать петли непосредственно из узлов DOM с использованием методов Object.
const funcs = [1, 2, 3].map(i => () => console.log(i));
funcs.map(fn => fn())
const funcs = [1, 2, 3].map(i => () => console.log(i));
funcs.map(fn => fn())
Основная проблема с кодом, показанным OP, заключается в том, что i никогда не читается до второго цикла. Чтобы продемонстрировать, представьте, что вы видите ошибку внутри кода
funcs[i] = function() { // and store them in funcs
throw new Error("test");
console.log("My value: " + i); // each should log its value.
};
Ошибка на самом деле не происходит до тех пор, пока funcs[someIndex] не будет выполнен (). Используя эту же логику, должно быть очевидно, что значение i также не будет собрано до этой точки. Как только исходный цикл завершится, i++ добавит i к значению 3, что приведет к сбою условия i < 3 и завершению цикла. На этом этапе i является 3, поэтому, когда используется funcs[someIndex](), и i оценивается, он равен 3 - каждый раз.
Чтобы пройти мимо этого, вы должны оценить i, поскольку он встречается. Обратите внимание, что это уже произошло в форме funcs[i] (где есть 3 уникальных индекса). Существует несколько способов захвата этого значения. Один из них - передать его в качестве параметра функции, которая уже несколько раз показана здесь.
Другой вариант - построить объект функции, который сможет закрыть эту переменную. Это может быть выполнено таким образом
jsFiddle Demo
funcs[i] = new function() {
var closedVariable = i;
return function(){
console.log("My value: " + closedVariable);
};
};
Бит опоздал на вечеринку, но я изучал эту проблему сегодня и заметил, что многие ответы не полностью касаются того, как Javascript обрабатывает области, что по сути сводится к этому.
So как упоминалось многими другими, проблема в том, что внутренняя функция ссылается на одну и ту же переменную i. Итак, почему бы нам просто не создать новую локальную переменную на каждой итерации и вместо этого иметь ссылку на внутреннюю функцию?
//overwrite console.log() so you can see the console output
console.log = function(msg) {document.body.innerHTML += '<p>' + msg + '</p>';};
var funcs = {};
for (var i = 0; i < 3; i++) {
var ilocal = i; //create a new local variable
funcs[i] = function() {
console.log("My value: " + ilocal); //each should reference its own local variable
};
}
for (var j = 0; j < 3; j++) {
funcs[j]();
}
Как и раньше, где вызывается каждая внутренняя функция последнее значение, присвоенное i, теперь каждая внутренняя функция просто выводит последнее значение, присвоенное ilocal. Но не должна ли каждая итерация иметь свою собственную ilocal?
Оказывается, в этом и проблема. Каждая итерация разделяет одну и ту же область, поэтому каждая итерация после первого просто переписывается ilocal. Из MDN:
Важно: JavaScript не имеет области блока. Переменные, введенные с блоком, привязаны к содержащейся функции или скрипту, а эффекты их настройки сохраняются за пределами самого блока. Другими словами, операторы блоков не вводят область. Хотя «автономные» блоки являются допустимым синтаксисом, вы не хотите использовать автономные блоки в JavaScript, потому что они не делают то, что, по вашему мнению, они делают, если вы думаете, что они делают что-то вроде таких блоков на C или Java.Повторяется для акцента:
JavaScript не имеет области блока. Переменные, введенные с блоком, привязаны к содержащейся функции или скрипту. Мы можем увидеть это, проверив ilocal, прежде чем объявить его на каждой итерации:
//overwrite console.log() so you can see the console output
console.log = function(msg) {document.body.innerHTML += '<p>' + msg + '</p>';};
var funcs = {};
for (var i = 0; i < 3; i++) {
var ilocal = i; //create a new local variable
funcs[i] = function() {
console.log("My value: " + ilocal); //each should reference its own local variable
};
}
for (var j = 0; j < 3; j++) {
funcs[j]();
}
Именно поэтому эта ошибка настолько сложна. Несмотря на то, что вы обновляете переменную, Javascript не будет вызывать ошибку, и JSLint даже не выдаст предупреждение. Именно поэтому лучший способ решить эту проблему - воспользоваться преимуществами закрытия, что по сути является идеей, что в Javascript внутренние функции имеют доступ к внешним переменным, потому что внутренние области «заключают» внешние области.
[ ! d18]
Это также означает, что внутренние функции «удерживают» внешние переменные и сохраняют их, даже если внешняя функция возвращается. Чтобы использовать это, мы создаем и вызываем функцию-оболочку исключительно для создания новой области, объявляем ilocal в новой области и возвращаем внутреннюю функцию, которая использует ilocal (подробнее объяснение ниже):
//overwrite console.log() so you can see the console output
console.log = function(msg) {document.body.innerHTML += '<p>' + msg + '</p>';};
var funcs = {};
for (var i = 0; i < 3; i++) {
var ilocal = i; //create a new local variable
funcs[i] = function() {
console.log("My value: " + ilocal); //each should reference its own local variable
};
}
for (var j = 0; j < 3; j++) {
funcs[j]();
}
Создание внутренней функции внутри функции-обертки дает внутренней функции частную среду, доступ к которой может получить только «закрытие». Таким образом, каждый раз, когда мы вызываем функцию-оболочку, мы создаем новую внутреннюю функцию с ее собственной отдельной средой, гарантируя, что переменные ilocal не сталкиваются и не перезаписывают друг друга. Несколько незначительных оптимизаций дают окончательный ответ, который дали многие другие пользователи SO:
//overwrite console.log() so you can see the console output
console.log = function(msg) {document.body.innerHTML += '<p>' + msg + '</p>';};
var funcs = {};
for (var i = 0; i < 3; i++) {
var ilocal = i; //create a new local variable
funcs[i] = function() {
console.log("My value: " + ilocal); //each should reference its own local variable
};
}
for (var j = 0; j < 3; j++) {
funcs[j]();
}
Обновить
Теперь, когда основной поток ES6, мы можем использовать новое ключевое слово let для создания переменных с блочным диапазоном:
//overwrite console.log() so you can see the console output
console.log = function(msg) {document.body.innerHTML += '<p>' + msg + '</p>';};
var funcs = {};
for (let i = 0; i < 3; i++) { // use "let" to declare "i"
funcs[i] = function() {
console.log("My value: " + i); //each should reference its own local variable
};
}
for (var j = 0; j < 3; j++) { // we can use "var" here without issue
funcs[j]();
}
Посмотрите, как легко это сейчас! Для получения дополнительной информации см. [D7] MDN , на котором основана моя информация.
Прежде всего, поймите, что не так с этим кодом:
var funcs = [];
for (var i = 0; i < 3; i++) { // let's create 3 functions
funcs[i] = function() { // and store them in funcs
console.log("My value: " + i); // each should log its value.
};
}
for (var j = 0; j < 3; j++) {
funcs[j](); // and now let's run each one to see
}
Здесь, когда инициализируется массив funcs[], i увеличивается, массив funcs инициализируется и размер массива func равен 3, поэтому i = 3,. Теперь, когда вызывается funcs[j](), он снова использует переменную i, которая уже была увеличена до 3.
Теперь, чтобы решить эту проблему, у нас есть много вариантов. Ниже приведены два из них:
Мы можем инициализировать i с помощью let или инициализировать новую переменную index с помощью let и сделать ее равной i. Поэтому, когда вызов выполняется, index будет использоваться, и его область действия закончится после инициализации. И для вызова снова будет инициализирован index:var funcs = [];
for (var i = 0; i < 3; i++) {
let index = i;
funcs[i] = function() {
console.log("My value: " + index);
};
}
for (var j = 0; j < 3; j++) {
funcs[j]();
}
Другой вариант может состоять в том, чтобы ввести tempFunc, который возвращает действительную функцию: var funcs = [];
function tempFunc(i){
return function(){
console.log("My value: " + i);
};
}
for (var i = 0; i < 3; i++) {
funcs[i] = tempFunc(i);
}
for (var j = 0; j < 3; j++) {
funcs[j]();
}
for (var i = 0; i < 3; i++) {
createfunc(i)();
}
function createfunc(i) {
return function(){console.log("My value: " + i);};
}
http://jsfiddle.net/7P6EN/
Попробуйте:
var funcs = [];
for (var i = 0; i < 3; i++) {
funcs[i] = (function(index) {
return function() {
console.log("My value: " + index);
};
}(i));
}
for (var j = 0; j < 3; j++) {
funcs[j]();
}
Edit (2014):
Лично я думаю, что более недавний ответ @ Aust об использовании .bind - лучший способ сделать такие вещи Теперь. Также есть _.partial lo-dash / underscore, когда вам не нужно или хотите взаимодействовать с bind thisArg.
Ваш код не работает, потому что он делает это:
Create variable `funcs` and assign it an empty array;
Loop from 0 up until it is less than 3 and assign it to variable `i`;
Push to variable `funcs` next function:
// Only push (save), but don't execute
**Write to console current value of variable `i`;**
// First loop has ended, i = 3;
Loop from 0 up until it is less than 3 and assign it to variable `j`;
Call `j`-th function from variable `funcs`:
**Write to console current value of variable `i`;**
// Ask yourself NOW! What is the value of i?
Теперь вопрос в том, каково значение переменной i при вызове функции? Поскольку первый цикл создается с условием i < 3, он немедленно останавливается, когда условие ложно, поэтому оно i = 3.
Вам нужно понять, что со временем, когда ваши функции будут созданы, ни один из их кодов не будет выполнен, он сохраняется только позже. Поэтому, когда они вызываются позже, интерпретатор выполняет их и спрашивает: «Каково текущее значение i?»
Итак, ваша цель - сначала сохранить значение функции i для функции и только после этого сохраните функцию до funcs. Это можно сделать следующим образом:
var funcs = [];
for (var i = 0; i < 3; i++) { // let's create 3 functions
funcs[i] = function(x) { // and store them in funcs
console.log("My value: " + x); // each should log its value.
}.bind(null, i);
}
for (var j = 0; j < 3; j++) {
funcs[j](); // and now let's run each one to see
}
Таким образом, каждая функция будет иметь свою собственную переменную x, и мы устанавливаем значение x на значение i на каждой итерации.
Это только один из нескольких способов решения этой проблемы.