В документах MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of
for...of
Конструкция описана , чтобы иметь возможность перебрать «Iterable» объекты. Но есть ли хороший способ решить, является ли объект повторяемым?
Я пытался найти общие свойства для массивов, итераторов и генераторов, но не смог.
Помимо выполнения for ... of
в блоке try и проверки ошибок типа, есть ли чистый способ сделать это?
javascript
Саймонзак
источник
источник
iterator()
метод ». Тем не менее, поскольку это черновик, только проверка может зависеть от реализации. Какую среду вы используете?Ответы:
Правильный способ проверки итерабельности следующий:
Почему это работает (подробный итеративный протокол): https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Iteration_protocols
Поскольку мы говорим о for..of, я полагаю, мы придерживаемся образа мышления ES6.
Кроме того, не удивляйтесь, что эта функция возвращает,
true
еслиobj
является строкой, поскольку строки повторяют свои символы.источник
Symbol.iterator in Object(obj)
,.return typeof obj[Symbol.iterator] === 'function'
? «Чтобы быть итерируемым, объект должен реализовывать метод @@ iterator» - он определяет методtypeof Object(obj)[Symbol.iterator] === 'function'
работать во всех случаях?Почему так многословно?
источник
Readability > Cleverness
всегда возвращаетсяtrue
.Readability > Cleverness
, сокращение переменнойobject
доo
никому не помогает. 2. Пустая строка''
повторяется и поэтому должна возвращатьсяtrue
.isIterable
.На самом деле самое простое решение:
Object
обернет все, что не является объектом, в один, позволяяin
оператору работать, даже если исходное значение не является объектом.null
иundefined
превращаются в пустые объекты, поэтому нет необходимости в обнаружении крайнего случая, а строки обертываются в объекты String, которые можно итерировать.источник
Symbol.iterator
.Object
этого типа проверки расточительно.Object
реализована функция, но она создает новый объект только в том случае, еслиvalue
это еще не объект. Я бы ожидать , что сочетаниеin
иObject(...)
быть чем - то браузер двигатели могут легко оптимизировать, в отличие говорятvalue !== undefined && value !== null && value[Symbol.iterator] && true
. Кроме того, он очень удобочитаемый, что меня волнует.В качестве примечания: ОСТЕРЕГАЙТЕСЬ определения итерации . Если вы переходите с других языков, вы ожидаете, что что-то, что вы можете перебирать, например,
for
цикл является повторяемым . Боюсь, что это не тот случай, когда итерация означает что-то, что реализует протокол итерации .Чтобы прояснить ситуацию, все приведенные выше примеры возвращаются
false
к этому объекту,{a: 1, b: 2}
потому что этот объект не реализует протокол итерации. Таким образом, вы не сможете перебирать его с помощьюfor...of
НО, вы все еще можете с помощьюfor...in
.Поэтому, если вы хотите избежать болезненных ошибок, сделайте свой код более конкретным, переименовав метод, как показано ниже:
источник
undefined
?object !== null
в своем ответе, но вы делаете этоobject != null
так, чтоundefined
в этом конкретном случае он не нарушает . Я соответствующим образом обновил свой ответ.hasIterationProtocol('')
должен вернутьсяtrue
! Как насчет того, чтобы удалить свой код и просто оставить повторяющийся раздел объяснений, который является единственным, что добавляет реальную ценность / что-то новое в ваш ответ.true
, удалив часть старого ответа, я объединил обе функции и забыл о строгом сравнении. Теперь я вернул исходный ответ, который работал нормально.Object(...)
, хороший улов. Но в этом случае нулевая проверка не нужна.Для асинхронного итераторов вы должны проверить «Symbol.asyncIterator» вместо «Symbol.iterator»:
источник
В настоящее время, как уже говорилось, чтобы проверить,
obj
является ли итерация, просто выполнитеИсторический ответ (более не действующий)
В
for..of
конструкция является частью проекта спецификации языка ECMASCript 6-го издания. Так что это могло измениться до финальной версии.В этом черновике повторяющиеся объекты должны иметь функцию
iterator
как свойство.Вы можете проверить, является ли объект повторяющимся, следующим образом:
источник
Если вы хотите действительно проверить, является ли переменная объектом (
{key: value}
) или массивом ([value, value]
), вы можете сделать это:источник