Firefox의 JS 엔진은 다음 코드와 같은 구문에서 foreach를 지원한다고 들었습니다.
FireFox만 지원하므로 거의 모든 JS 코드에서는 이 기능을 사용하지 않습니다.
하지만 ActionScript는 기본적으로 for Each 구문을 지원합니다. 배열, 벡터 또는 사전에 관계없이 열거 가능한 객체라면 for in 및 for Each in이 될 수 있습니다.
이전에는 "each"라는 단어를 입력하기가 너무 귀찮기 때문에 항상 익숙한 for in을 사용하여 횡단했습니다.
그런데 오늘 곰곰히 생각해보고 데이터 구조의 관점에서 분석해 보니 JS든 AS든 for in과 for Each in 사이에는 본질적인 효율성 차이가 있다는 걸 느꼈습니다.
이유는 간단합니다. 배열은 진정한 의미의 배열이 아닙니다!
배열의 진정한 의미는 무엇인가요? 물론 전통언어에서는 type[]으로 정의된 데이터형이며, 모든 요소는 연속적으로 저장된다.
"배열"도 배열을 의미하지만 JS에 익숙한 사람들은 이것이 실제로 비선형 의사 배열이며 아래 첨자는 임의의 숫자일 수 있다는 것을 알고 있습니다. arr[1000000]을 쓴다고 해서 실제로 100만 개의 요소를 수용할 수 있는 공간이 적용되는 것은 아니지만 1000000을 해당 해시 값으로 변환하므로 작은 저장 공간에 해당하므로 많은 메모리가 절약됩니다.
예를 들어 다음과 같은 배열이 있습니다.
for...in을 사용하여 배열을 순회하는 것은 매우 번거로운 과정입니다.
순회 중에 arr[k]에 액세스할 때마다 Hash(k) 계산을 수행해야 하며, 해시 테이블의 용량을 기준으로 모듈로를 수행해야 합니다. 충돌이 있는 경우 최종 값 결과를 찾아야 합니다.
foreach...in 구문이 지원되는 경우 내부 데이터 구조에 따라 훨씬 더 빨라질 것으로 결정됩니다.
Array에서는 각 값을 노드로 직접 사용하고 연결리스트를 통해 관리합니다. 값이 추가되거나 삭제될 때마다 해당 링크 관계가 업데이트됩니다.
각...in을 탐색할 때 해시 계산 없이 첫 번째 노드부터 역방향으로만 반복하면 됩니다.
물론 AS3의 Vector와 같은 선형 배열의 경우 둘 사이에 큰 차이가 없으며 HTML5의 이진 배열 ArrayBuffer도 마찬가지입니다. 그러나 이론적 관점에서 보면 arr이 연속 선형 배열이더라도 for Each in이 여전히 더 빠릅니다.
for...in을 탐색할 때 arr[k]에 액세스할 때마다 아래 첨자가 나타납니다. out-of-bounds 검사를 수행해야 하며 각 in에 대해 내부 연결 목록을 기반으로 하위 계층의 반복 변수를 직접 피드백하여 out-of-bounds 검사 프로세스를 저장합니다.