пример:
var arr = ["one","two","three"];
arr.forEach(function(part){
part = "four";
return "four";
})
alert(arr);
Массив все еще имеет свои исходные значения, есть ли способ получить доступ для записи элементов массива из итерационной функции?
x=[2,3,4]; x=x.map(n=>n*2); // [4,6,8]
Ответы:
Обратному вызову передается элемент, индекс и сам массив.
edit - как отмечено в комментарии,
.forEach()
функция может принимать второй аргумент, который будет использоваться в качестве значения приthis
каждом вызове обратного вызова:Этот второй пример показывает
arr
, что он настроен так же, как иthis
в обратном.forEach()
вызове. Кто-то может подумать, что массив, участвующий в вызове, может быть значением по умолчаниюthis
, но по какой-то причине это не так;this
будет,undefined
если этот второй аргумент не указан.(Примечание: вышеприведенный материал о
this
не применяется, если обратный вызов является=>
функцией, потому чтоthis
никогда не привязывается ни к чему, когда такие функции вызываются.)Также важно помнить, что в прототипе Array предусмотрено целое семейство похожих утилит, и в Stackoverflow всплывает множество вопросов о той или иной функции, так что лучшим решением будет просто выбрать другой инструмент. У тебя есть:
forEach
за то, что вы делаете с или с каждой записью в массиве;filter
для создания нового массива, содержащего только подходящие записи;map
для создания нового массива один к одному путем преобразования существующего массива;some
проверить, соответствует ли хотя бы один элемент в массиве некоторому описанию;every
проверить, соответствуют ли все записи в массиве описанию;find
искать значение в массивеи так далее. MDN ссылка
источник
part
(или дажеo
в es6) не определено? как получить повторное значение?part
был бы,undefined
если элемент массива был назначенundefined
явно. «Пустые» слоты массива (элемент массива, которому никогда не назначалось какое-либо значение) пропускаются.forEach()
и большинством других методов итерации массива..forEach()
также принимает второй аргументthisArg
, который вы можете использовать какthis
внутри обратного вызова. ПРИМЕЧАНИЕ: это аргумент, а.forEach
не аргумент обратного вызова.this
переданный в качестве второго аргумента для.forEach()
, необходимо передать функцию обратного вызова с использованием синтаксисаfunction()
, поскольку использование функции стрелки ES6() => {}
не связывает контекст.Давайте постараемся сделать это простым и обсудим, как это на самом деле работает. Это связано с типами переменных и параметрами функций.
Вот ваш код, о котором мы говорим:
Прежде всего, вот где вы должны прочитать о Array.prototype.forEach ():
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach
Во-вторых, давайте кратко поговорим о типах значений в JavaScript.
Примитивы (undefined, null, String, Boolean, Number) хранят фактическое значение.
например:
var x = 5;
Типы ссылок (пользовательские объекты) хранят расположение объекта в памяти.
например:
var xObj = { x : 5 };
И в-третьих, как работают параметры функции.
В функциях параметры всегда передаются по значению.
Поскольку
arr
это массив строк, это массив примитивных объектов, что означает, что они хранятся по значению.Таким образом, для вашего кода выше это означает, что каждый раз, когда forEach () выполняет итерацию,
part
равен одному и тому же значениюarr[index]
, но не одному и тому же объекту .part = "four";
изменитpart
переменную, но оставит вarr
покое.Следующий код изменит нужные значения:
Теперь, если массив
arr
был массивом ссылочных типов , следующий код будет работать, потому что ссылочные типы хранят место в памяти объекта вместо фактического объекта.Ниже показано, что вы можете изменить
part
указатель на новый объект, оставив объекты вarr
одиночестве:источник
In functions, parameters are always passed by value.
насчет второго примера?Массив:
[1, 2, 3, 4]
Результат:
["foo1", "foo2", "foo3", "foo4"]
Array.prototype.map()
Сохранить оригинальный массивArray.prototype.forEach()
Переопределить исходный массивисточник
let arr1 = ["1", 2, 3, 4]; arr1.map(function(v) { return "foo"+ v; }); console.log( arr );
Array.prototype.map () Никогда не изменяйте исходный массив, для каждого изменения.map
может определенно мутировать свой массив иforEach
, в общем, не делает.Javascript передается по значению, а это означает,
part
что это копия значения в массиве.Чтобы изменить значение, обратитесь к самому массиву в вашем цикле.
arr[index] = 'new value';
источник
part
, копируется ли оно - хотя вы правы, что переменная не указатель, а значениезамените его индексом массива.
источник
Вот аналогичный ответ с использованием
=>
функции стиля:дает результат:
self
Параметр не является строго необходимым с функцией стрелки стиля, тактоже работает.
источник
Функция .forEach может иметь функцию обратного вызова (eachelement, elementIndex). Итак, в основном вам нужно сделать следующее:
Или, если вы хотите сохранить исходный массив, вы можете сделать его копию перед выполнением вышеуказанного процесса. Чтобы сделать копию, вы можете использовать:
источник
map()
вместоforEach()
.map()
перебирает исходный массив и возвращает новый массив, содержащий [измененную] копию оригинала: исходный массив остается неизменным.С помощью методов объекта Array вы можете изменять содержимое Array, но по сравнению с базовым циклом for эти методы лишены одной важной функциональности. Вы не можете изменить индекс на ходу.
Например, если вы удалите текущий элемент и поместите его в другую позицию индекса в том же массиве, вы можете легко это сделать. Если вы переместите текущий элемент на предыдущую позицию, в следующей итерации проблем не будет, вы получите тот же следующий элемент, как если бы вы ничего не делали.
Рассмотрим этот код, в котором мы перемещаем элемент в позиции индекса 5 в позицию индекса 2, когда индекс насчитывает до 5.
Однако если мы переместим текущий элемент куда-нибудь за пределы текущей позиции индекса, все станет немного грязно. Затем следующий элемент будет перемещен в позицию перемещенных элементов, и на следующей итерации мы не сможем увидеть или оценить его.
Рассмотрим этот код, в котором мы перемещаем элемент с позиции индекса 5 в позицию индекса 7, если индекс насчитывает до 5.
Таким образом, мы никогда не встречали 6 в цикле. Обычно в цикле for ожидается, что значение индекса будет уменьшаться при перемещении элемента массива вперед, чтобы ваш индекс оставался на той же позиции в следующем цикле, и вы все равно сможете оценить смещение элемента на место удаленного элемента. Это невозможно с помощью методов массива. Вы не можете изменить индекс. Проверьте следующий код
Как вы видите, когда мы уменьшаем,
i
он будет продолжаться не с 5, а с 6, с которого он был оставлен.Так что имейте это в виду.
источник
Чтобы полностью добавить или удалить элементы, которые могли бы изменить индекс, с помощью расширения zhujy_8833 предложения slice () для перебора копии, просто посчитайте количество уже удаленных или добавленных элементов и измените индекс соответствующим образом. Например, чтобы удалить элементы:
Чтобы вставить элементы перед:
Чтобы вставить элементы после:
Чтобы заменить элемент:
Примечание: если реализованы вставки 'before' и 'after', код должен обрабатывать вставки 'before' первым, иначе все будет не так, как ожидалось
источник
Вы можете попробовать это, если хотите переопределить
источник