Применение различных циклов for для массива, в чем разница?
Доброго времени суток! Решая задачки по JS на CodeWars.com наткнулся на вопрос связанный с циклом for для массива. Суть задачи, написать функцию которая преобразует массив с числами [1,2,3,4,5,6,7,8,9,0], в формат "(123) 456-7890".
В первом случае, когда используем цикл for(let i = 0; i < arr.length, i++), то получаем результат тот что нужен. Уже во втором случае, когда используем цикл for(let item of arr) я получаю не преобразованный формат. Помогите разобраться, почему во втором случае в теле цикла for не перезаписываются значения?!
let phoneNumber = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
function createPhoneNumber1(numb){
let phoneNumberInType = "(***) ***-****".split("");
let count = 0;
for(let i=0; i < phoneNumberInType.length; i++) {
if(phoneNumberInType[i] == "*") {
phoneNumberInType[i] = numb[count++] ;
}
}
return phoneNumberInType.join('');
}
console.log(createPhoneNumber1(phoneNumber)); // Получаем строку "(123) 456-7890"
function createPhoneNumber2(numb){
let phoneNumberInType = "(***) ***-****".split("");
let count = 0;
for(let item of phoneNumberInType) {
if(item == "*") {
item = numb[count++];
}
}
return phoneNumberInType.join('');
}
console.log(createPhoneNumber2(phoneNumber)); // Получаем строку "(***) ***-****"
Ответы (2 шт):
Тут тип цикла не важен. Во втором варианте вы изменяете значение переменной, но не трогаете массив. Точно также массив не изменится если сделать вот так:
let item = phoneNumberInType[0]
item = null //здесь присвоение любого значения не изменяет массив
Если же очень хочется решить эту задачу с for ... of , то можно сделать так:
function createPhoneNumber2(numb){
let phoneNumberInType = "(***) ***-****".split("");
let count = 0;
for(let [key, item] of phoneNumberInType.entries()) {
if(item == "*") {
phoneNumberInType[key] = numb[count++];
}
}
return phoneNumberInType.join('');
}
Нужно изменять значение в самом массиве, для этого нужно знать индекс. Этот тип цикла не предполагает индексов, но мы можем сами его создать с помощью метода entries.
let phoneNumber = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
function createPhoneNumber2(numb){
let phoneNumberInType = "(***) ***-****".split("");
let count = 0;
let index = 0; // введем дополнительную переменную, чтобы показать, что мы создаем новую переменную при каждой итерации.
for(let item of phoneNumberInType) { // тут при каждой итерации цикла создается новая переменная item, которая по значению равна очередному значению в массиве.
if(item == "*") {
item = numb[count++]; // тут вы меняете не элемент массива, а новенькую переменную, которая была создана при очередной итерации.
console.log(`item: ${item}, phoneNumberInType[${index}]: ${phoneNumberInType[index]}`) // чтобы показать, что элементы phoneNumberInType остаются не тронуты
}
index++; // при каждей итерации меняем индекс (аналог i в for)
}
return phoneNumberInType.join('');
}
console.log(createPhoneNumber2(phoneNumber)); // Получаем строку "(***) ***-****"
let friends = [{name: 'Vlad'}, {name: 'Victor'}, {name: 'Igor'}];
for (let friend of friends) { // Обьекты копируются по ссылке, по-этому вы можете изменять их в цикле for..of. (Новый обьект не создается).
friend.name = 'Tolik';
}
console.log(friends); // Кажется в друзьях остались одни Толики.
let friends = [{name: 'Vlad'}, {name: 'Victor'}, {name: 'Igor'}];
for (let friend of friends) {
friend = {name: 'Tolik'}; // В данном случае создается новый обьект, а ссылка на него переприсваивается переменной, которая раньше ссылалась на обьет в массиве. При этом сам обьект, находящийся в массиве никак не задет.
}
console.log(friends); // Ничего не изменилось