[javascript] 무언가가 반복 가능한지 확인하기

MDN 문서 : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for…of

for...of구조는 반복 “반복 가능한”오브젝트 할 수 있도록 설명되어 있습니다. 그러나 객체가 반복 가능한지 여부를 결정하는 좋은 방법이 있습니까?

배열, 반복기 및 생성기에 대한 공통 속성을 찾으려고했지만 그렇게 할 수 없었습니다.

for ... oftry 블록에서 수행하고 유형 오류를 확인하는 것 외에이 작업을 수행하는 깨끗한 방법이 있습니까?



답변

반복성을 확인하는 올바른 방법은 다음과 같습니다.

function isIterable(obj) {
  // checks for null and undefined
  if (obj == null) {
    return false;
  }
  return typeof obj[Symbol.iterator] === 'function';
}

이것이 작동하는 이유 (심층 반복 가능한 프로토콜) : https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Iteration_protocols

for..of에 대해 이야기하고 있기 때문에 우리는 ES6 사고 방식에 있다고 가정합니다.

또한 문자열이 문자를 반복하므로이 함수가 문자열 인 true경우 반환한다는 사실에 놀라지 마십시오 obj.


답변

왜 그렇게 장황합니까?

const isIterable = object =>
  object != null && typeof object[Symbol.iterator] === 'function'


답변

가장 간단한 해결책은 실제로 다음과 같습니다.

function isIterable (value) {
  return Symbol.iterator in Object(value);
}

Objectin원래 값이 Object가 아니더라도 연산자가 작업 할 수 있도록 개체가 아닌 모든 것을 하나로 묶습니다. nullundefined에지의 경우 탐지를위한 필요가 없습니다 있도록 빈 개체로 설정하고, 문자열을 반복 가능한이다 String 객체에 랩 얻을.


답변

(!) 참고로, 조심 의 정의에 대해 반복 가능한 . 다른 언어에서 온 경우 반복 할 수있는 무언가를 기대할 수 있습니다. 예를 들어 for루프는 반복 가능 합니다. 나는 iterable반복 프로토콜 을 구현하는 것을 의미 하는 경우가 아닙니다 .

더 명확하게하기 위해 위의 모든 예제 false는이 객체 {a: 1, b: 2}가 반복 프로토콜을 구현하지 않기 때문에이 객체를 반환 합니다. 당신은 그것을 반복 할 수 없습니다 그래서 for...of 하지만 당신은 여전히 A를 할 수 있습니다 for...in.

따라서 고통스러운 실수를 피하려면 아래와 같이 메서드 이름을 변경하여 코드를 더 구체적으로 만드십시오.

/**
 * @param variable
 * @returns {boolean}
 */
const hasIterationProtocol = variable =>
    variable !== null && Symbol.iterator in Object(variable);


답변

요즘에는 이미 언급했듯이 obj반복 가능한지 테스트하려면

obj != null && typeof obj[Symbol.iterator] === 'function' 

역사적 답변 (더 이상 유효하지 않음)

for..of구성은 ECMASCript 6 판 언어 사양 초안의 일부입니다. 따라서 최종 버전 이전에 변경 될 수 있습니다.

이 초안에서 반복 가능한 객체는 iterator속성으로서의 기능 을 가져야합니다 .

객체가 다음과 같이 반복 가능한지 확인할 수 있습니다.

function isIterable(obj){
   if(obj === undefined || obj === null){
      return false;
   }
   return obj.iterator !== undefined;
}


답변

들어 비동기 반복자 대신 ‘Symbol.iterator’의 ‘Symbol.asyncIterator’를 확인한다 :

async function* doSomething(i) {
    yield 1;
    yield 2;
}

let obj = doSomething();

console.log(typeof obj[Symbol.iterator] === 'function');      // false
console.log(typeof obj[Symbol.asyncIterator] === 'function'); // true


답변

실제로 변수가 객체 ( {key: value})인지 배열 ( [value, value]) 인지 확인하려면 다음 과 같이 할 수 있습니다.

const isArray = function (a) {
    return Array.isArray(a);
};

const isObject = function (o) {
    return o === Object(o) && !isArray(o) && typeof o !== 'function';
};

function isIterable(variable) {
    return isArray(variable) || isObject(variable);
}