В чем разница между (для... в) и (для... из) операторов в JavaScript?

Я знаю, что такое цикл for... in (он повторяется по ключу), но впервые слышал о for... of (он повторяется по значению). Я запутался с циклом for... of. Я не получил adject. Это код ниже:

var arr = [3, 5, 7];
arr.foo = "hello";

for (var i in arr) {
   console.log(i); // logs "0", "1", "2", "foo"
}

for (var i of arr) {
   console.log(i); // logs "3", "5", "7"
    //it is does not log "3", "5", "7","hello"
}

Что я получил, так это for... of перебирает значения свойств. тогда почему он не регистрирует (возвращает) "3", "5", "7","hello" вместо "3", "5", "7"? но цикл for... in повторяется по каждому ключу ("0", "1", "2", "foo"). Здесь цикл for... in также перебирает ключ foo. но для... не повторения значения свойства foo, т.е. "hello". Почему это так?

Короче говоря:

здесь я утешаю петлю for... of. это должен быть журнал "3", "5", "7","hello", но здесь он регистрирует "3", "5", "7". Почему?

Пример ссылки

Ответ 2

Я нахожу полный ответ по адресу: https://www.typescriptlang.org/docs/handbook/iterators-and-generators.html (Хотя это для типа script, это тоже самое для javascript)

Оба оператора for..of и for..in повторяют списки; ценности iterated on отличаются, но for..in возвращает список ключей на объект, который повторяется, тогда как for..of возвращает список значений числовых свойств объекта, который повторяется.

Вот пример, демонстрирующий это различие:

let list = [4, 5, 6];

for (let i in list) {
   console.log(i); // "0", "1", "2",
}

for (let i of list) {
   console.log(i); // "4", "5", "6"
}

Другое различие заключается в том, что для..in действует любой объект; это служит как способ проверки свойств объекта. for..of с другой стороны в основном, интересуются значениями итерируемых объектов. Встроенный объекты типа Map и Set implement Symbol.iterator, позволяющие доступ к сохраненным значениям.

let pets = new Set(["Cat", "Dog", "Hamster"]);
pets["species"] = "mammals";

for (let pet in pets) {
   console.log(pet); // "species"
}

for (let pet of pets) {
    console.log(pet); // "Cat", "Dog", "Hamster"
}

Ответ 3

Для... в цикле

Контур for...in улучшает слабые стороны цикла for, устраняя логику счета и условие выхода.

Пример:

const digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

for (const index in digits) {
  console.log(digits[index]);
}

Но вам все же приходится иметь дело с проблемой использования индекса для доступа к значениям массива, и это воняет; это почти делает его более запутанным, чем раньше.

Кроме того, цикл for... in может вызвать у вас большие проблемы, когда вам нужно добавить дополнительный метод в массив (или другой объект). Поскольку для циклов... в циклах по всем перечислимым свойствам это означает, что если вы добавите дополнительные свойства в прототип массива, то эти свойства также появятся в цикле.

Array.prototype.decimalfy = function() {
  for (let i = 0; i < this.length; i++) {
    this[i] = this[i].toFixed(2);
  }
};

const digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

for (const index in digits) {
  console.log(digits[index]);
}

Печать

0

1

2

3

4

5

6

7

-

9

function() {     для (пусть я = 0; я < this.length; я ++) {     это [i] = this [i].toFixed(2);     }     }

Вот почему для циклов... в циклах не рекомендуется при переходе по массивам.

ПРИМЕЧАНИЕ. Цикл forEach - это другой тип цикла for в JavaScript. Однако forEach() на самом деле является методом массива, поэтому его можно использовать только исключительно с массивами. Также нет возможности остановить или forEach. Если вам нужен этот тип поведения в вашем цикле, youll должны использовать базовый цикл.

Для... цикла

Цикл for...of используется для циклического преобразования любых типов данных, которые являются итерабельными.

Пример:

const digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

for (const digit of digits) {
  console.log(digit);
}

Печать

0

1

2

3

4

5

6

7

-

9

Это делает цикл for... наиболее сжатым для всех циклов for.

Но подождите, theres больше! Для цикла... также есть некоторые дополнительные преимущества, которые устраняют слабые стороны циклов for и for... в циклах.

Вы можете остановить или разбить a для... цикла в любое время.

const digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

for (const digit of digits) {
  if (digit % 2 === 0) {
    continue;
  }
  console.log(digit);
}

Печать

1

3

5

7

9

И вам не нужно беспокоиться о добавлении новых свойств к объектам. Цикл for... цикла будет только перебирать значения в объекте.

Ответ 4

Оператор for...in перебирает перечисляемые свойства объекта в произвольном порядке. Перечислимыми свойствами являются те свойства, для которых внутренний флаг [[Enumerable]] установлен в значение true, поэтому, если в цепочке прототипов есть какое-либо перечислимое свойство, цикл for...in будет выполнять итерации по ним.

Оператор for...of выполняет итерации по данным, которые итерируемый объект определяет для итерации.

Пример:

Object.prototype.objCustom = function() {}; 
Array.prototype.arrCustom = function() {};

let iterable = [3, 5, 7];

for (let i in iterable) {
  console.log(i); // logs: 0, 1, 2, "arrCustom", "objCustom"
}

for (let i in iterable) {
  if (iterable.hasOwnProperty(i)) {
    console.log(i); // logs: 0, 1, 2,
  }
}

for (let i of iterable) {
  console.log(i); // logs: 3, 5, 7
}

Как и ранее, вы можете пропустить добавление hasOwnProperty for...of циклов.

Ответ 5

Оператор for-in выполняет итерацию по перечислимым свойствам объекта в произвольном порядке.

Цикл будет перебирать все перечислимые свойства самого объекта и те объекты, которые наследует его прототип конструктора

Вы можете думать об этом как о "for in" в основном итерации и перечислять все ключи.

var str = 'abc';
var arrForOf = [];
var arrForIn = [];

for(value of str){
  arrForOf.push(value);
}

for(value in str){
  arrForIn.push(value);
}

console.log(arrForOf); 
// ["a", "b", "c"]
console.log(arrForIn); 
// ["0", "1", "2", "formatUnicorn", "truncate", "splitOnLast", "contains"]

Ответ 6

Разница for..in и for..of:

И for..in, и for..of являются циклическими конструкциями, которые используются для перебора структур данных. Разница лишь в том, что они повторяют:

  1. for..in перебирает все перечисляемые ключи свойств объекта
  2. for..of выполняет итерации по значениям итерируемого объекта. Примерами итерируемых объектов являются массивы, строки и списки узлов.

Пример:

let arr = ['el1', 'el2', 'el3'];

arr.addedProp = 'arrProp';

// elKey are the property keys
for (let elKey in arr) {
  console.log(elKey);
}

// elValue are the property values
for (let elValue of arr) {
  console.log(elValue)
}

Ответ 7

Есть некоторые уже определенные типы данных, которые позволяют легко их перебирать, например, Array, Map, String Objects

Обычный для in выполняет итерации по итератору и в ответ предоставляет нам ключи в порядке вставки, как показано в примере ниже.

  const numbers = [1,2,3,4,5];
   for(let number in number) {
     console.log(number);
   }

   // result: 0, 1, 2, 3, 4

Теперь, если мы попробуем то же самое для for, то в ответ он предоставит нам значения, а не ключи. например

  const numbers = [1,2,3,4,5];
   for(let numbers of numbers) {
    console.log(number);
  }

  // result: 1, 2, 3, 4, 5

Поэтому, глядя на оба итератора, мы можем легко различить разницу между ними.

Примечание: - Для работы только с Symbol.iterator

Поэтому, если мы попытаемся выполнить итерацию по обычному объекту, это выдаст нам ошибку e. g-

const Room = {
   area: 1000,
   height: 7,
   floor: 2
 }

for(let prop in Room) {
 console.log(prop);
 } 

// Result area, height, floor

for(let prop of Room) {
  console.log(prop);
 } 

Комната не повторяется

Теперь для итерации нам нужно определить ES6 Symbol.iterator, например:

  const Room= {
    area: 1000, height: 7, floor: 2,
   [Symbol.iterator]: function* (){
    yield this.area;
    yield this.height;
    yield this.floors;
  }
}


for(let prop of Room) {
  console.log(prop);
 } 

//Result 1000, 7, 2

В этом разница между For in и For of. Надеюсь, что это может очистить разницу.

Ответ 8

Все объяснили, почему возникает эта проблема, но все равно очень легко забыть об этом, а затем почесать голову, почему вы получили неправильные результаты. Особенно, когда вы работаете с большими наборами данных, когда результаты на первый взгляд кажутся хорошими.

Используя Object.entries вы Object.entries все свойства:

var arr = [3, 5, 7];
arr.foo = "hello";

for ( var [key, val] of Object.entries( arr ) ) {
   console.log( val );
}

/* Result:

3
5
7
hello

*/

Ответ 9

Еще одно различие между двумя циклами, о котором никто не упоминал ранее (источник):

Разрушение for...in не рекомендуется. Используйте for...of вместо.

Поэтому, если мы хотим использовать деструктуризацию в цикле, для получения как индекса, так и значения каждого элемента массива, мы должны использовать цикл for...of loop с entries() метода Array entries():

for (const [idx, el] of arr.entries()) {
    console.log( idx + ': ' + el );
}

Ответ 10

Я вижу много хороших ответов, но я решил поставить свои 5 центов только для того, чтобы иметь хороший пример:

Ибо в цикле

перебирает все перечисляемые реквизиты

let nodes = document.documentElement.childNodes;

for (var key in nodes) {
  console.log( key );
}

Ответ 11

Я нашел следующее объяснение из https://javascript.info/array очень полезным:

Один из самых старых способов циклического перемещения элементов массива - это циклы for по индексам:

let arr = ["Apple", "Orange", "Pear"];

for (let i = 0; i < arr.length; i++) { alert( arr[i] ); } But for arrays there is another form of loop, for..of:

let fruits = ["Apple", "Orange", "Plum"];

// iterates over array elements for (let fruit of fruits) { alert( fruit ); } The for..of doesnt give access to the number of the current element, just its value, but in most cases thats enough. And its shorter.

Технически, поскольку массивы являются объектами, их также можно использовать для..in:

let arr = ["Apple", "Orange", "Pear"];

for (let key in arr) { alert( arr[key] ); // Apple, Orange, Pear } But thats actually a bad idea. There are potential problems with it:

Цикл for..in перебирает все свойства, не только числовые.

В браузере и в других средах есть так называемые "подобные массиву" объекты, которые выглядят как массивы. То есть они имеют свойства длины и индексов, но могут также иметь другие нечисловые свойства и методы, которые нам обычно не нужны. Цикл for..in перечислит их все же. Поэтому, если нам нужно работать с объектами, похожими на массивы, то эти "дополнительные" свойства могут стать проблемой.

Цикл for..in оптимизирован для общих объектов, а не массивов, и, следовательно, в 10-100 раз медленнее. Конечно, все еще очень быстро. Ускорение может иметь значение только в узких местах. Но все же мы должны осознавать разницу.

Как правило, мы не должны использовать for..in для массивов.

Ответ 12

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

для.. in не создает список во время итерации, он выбирает значения, имеет смысл использовать его при итерации по типу массива.

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