JS의 네 가지 배열 탐색 방법( for , forEach() , for/in, for/of) 간의 차이점
JavaScript에서는 배열이나 객체를 탐색하는 여러 가지 방법이 있으며, 그 차이점은 매우 혼란스럽습니다. 에어비앤비 코딩 스타일for/in 및 for/of는 금지되어 있습니다. 이유를 아시나요?
이 글에서는 다음 네 가지 루프 구문의 차이점을 자세히 소개합니다.- < code>arr.forEach((v, i) => { /* ... */ })
for (let i = 0; i < arr.length; ++i)
arr.forEach((v, i) => { /* ... */ })
for (let i in arr)
for (const v of arr)
for (let i = 0; i < arr.length; ++i)
语法
使用for
和for/in
,我们可以访问数组的下标,而不是实际的数组元素值:
for (let i = 0; i < arr.length; ++i) { console.log(arr[i]); } for (let i in arr) { console.log(arr[i]); }
使用for/of
,则可以直接访问数组的元素值:
for (const v of arr) { console.log(v); }
使用forEach()
,则可以同时访问数组的下标与元素值:
arr.forEach((v, i) => console.log(v));
非数字属性
JavaScript 的数组就是 Object,这就意味着我们可以给数组添加字符串属性:
const arr = ["a", "b", "c"]; typeof arr; // 'object' arr.test = "bad"; // 添加非数字属性 arr.test; // 'abc' arr[1] === arr["1"]; // true, JavaScript数组只是特殊的Object
4 种循环语法,只有for/in
不会忽略非数字属性:
const arr = ["a", "b", "c"]; arr.test = "bad"; for (let i in arr) { console.log(arr[i]); // 打印"a, b, c, bad" }
正因为如此,使用for/in
遍历数组并不好。
其他 3 种循环语法,都会忽略非数字属性:
const arr = ["a", "b", "c"]; arr.test = "abc"; // 打印 "a, b, c" for (let i = 0; i < arr.length; ++i) { console.log(arr[i]); } // 打印 "a, b, c" arr.forEach((el, i) => console.log(i, el)); // 打印 "a, b, c" for (const el of arr) { console.log(el); }
要点: 避免使用for/in
来遍历数组,除非你真的要想要遍历非数字属性。可以使用 ESLint 的guard-for-in规则来禁止使用for/in
。
数组的空元素
JavaScript 数组可以有空元素。以下代码语法是正确的,且数组长度为 3:
const arr = ["a", , "c"]; arr.length; // 3
让人更加不解的一点是,循环语句处理['a',, 'c']
与['a', undefined, 'c']
的方式并不相同。
对于['a',, 'c']
,for/in
与forEach
会跳过空元素,而for
与for/of
则不会跳过。
// 打印"a, undefined, c" for (let i = 0; i < arr.length; ++i) { console.log(arr[i]); } // 打印"a, c" arr.forEach(v => console.log(v)); // 打印"a, c" for (let i in arr) { console.log(arr[i]); } // 打印"a, undefined, c" for (const v of arr) { console.log(v); }
对于['a', undefined, 'c']
,4 种循环语法一致,打印的都是"a, undefined, c"。
还有一种添加空元素的方式:
// 等价于`['a', 'b', 'c',, 'e']` const arr = ["a", "b", "c"]; arr[5] = "e";
还有一点,JSON 也不支持空元素:
JSON.parse('{"arr":["a","b","c"]}'); // { arr: [ 'a', 'b', 'c' ] } JSON.parse('{"arr":["a",null,"c"]}'); // { arr: [ 'a', null, 'c' ] } JSON.parse('{"arr":["a",,"c"]}'); // SyntaxError: Unexpected token , in JSON at position 12
要点: for/in
与forEach
会跳过空元素,数组中的空元素被称为"holes"。如果你想避免这个问题,可以考虑禁用forEach
:
parserOptions: ecmaVersion: 2018 rules: no-restricted-syntax: - error - selector: CallExpression[callee.property.name="forEach"] message: Do not use `forEach()`, use `for/of` instead
函数的 this
for
,for/in
与for/of
会保留外部作用域的this
。
对于forEach
, 除非使用箭头函数,它的回调函数的 this 将会变化。
使用 Node v11.8.0 测试下面的代码,结果如下:
"use strict"; const arr = ["a"]; arr.forEach(function() { console.log(this); // 打印undefined }); arr.forEach(() => { console.log(this); // 打印{} });
要点: 使用 ESLint 的no-arrow-callback
规则要求所有回调函数必须使用箭头函数。
Async/Await 与 Generators
还有一点,forEach()
不能与 Async/Await 及 Generators 很好的"合作"。
不能在forEach
回调函数中使用 await:
async function run() { const arr = ['a', 'b', 'c']; arr.forEach(el => { // SyntaxError await new Promise(resolve => setTimeout(resolve, 1000)); console.log(el); }); }
不能在forEach
回调函数中使用 yield:
function run() { const arr = ['a', 'b', 'c']; arr.forEach(el => { // SyntaxError yield new Promise(resolve => setTimeout(resolve, 1000)); console.log(el); }); }
对于for/of
来说,则没有这个问题:
async function asyncFn() { const arr = ["a", "b", "c"]; for (const el of arr) { await new Promise(resolve => setTimeout(resolve, 1000)); console.log(el); } } function* generatorFn() { const arr = ["a", "b", "c"]; for (const el of arr) { yield new Promise(resolve => setTimeout(resolve, 1000)); console.log(el); } }
当然,你如果将forEach()
的回调函数定义为 async 函数就不会报错了,但是,如果你想让forEach
按照顺序执行,则会比较头疼。
下面的代码会按照从大到小打印 0-9:
async function print(n) { // 打印0之前等待1秒,打印1之前等待0.9秒 await new Promise(resolve => setTimeout(() => resolve(), 1000 - n * 100)); console.log(n); } async function test() { [0, 1, 2, 3, 4, 5, 6, 7, 8, 9].forEach(print); } test();
要点: 尽量不要在forEach
中使用 aysnc/await 以及 generators。
结论
简单地说,for/of
是遍历数组最可靠的方式,它比for
循环简洁,并且没有for/in
和forEach()
那么多奇怪的特例。for/of
的缺点是我们取索引值不方便,而且不能这样链式调用forEach()
. forEach()
for (let i in arr)
li >
for (const v of arr)
구문
🎜for
및 < 사용 code >for/in을 사용하면 실제 배열 요소 값 대신 배열의 첨자에 액세스할 수 있습니다. 🎜for (const [i, v] of arr.entries()) { console.log(i, v); }
for/of
를 사용하면 요소 값에 직접 액세스할 수 있습니다. 배열: 🎜 rrreee🎜 forEach()
를 사용하면 배열의 첨자와 요소 값에 동시에 액세스할 수 있습니다. 🎜rrreee비숫자 속성
🎜JavaScript 배열은 객체입니다. 즉, 배열에 문자열 속성을 추가할 수 있습니다: 🎜rrreee🎜 4개의 루프 구문,for/in
만 숫자가 아닌 속성을 무시하지 않습니다: 🎜rrreee🎜 이 때문에 < code>for/in 배열을 반복하는 것은 좋지 않습니다🎜. 🎜🎜다른 3개의 루프 구문은 숫자가 아닌 속성을 무시합니다. 🎜rrreee🎜점: 실제로 반복하려는 경우가 아니면 for/in
을 사용하여 배열을 반복하지 마세요. -숫자 속성. ESLint의 guard-for-in🎜 규칙을 사용하여 for/in
. 🎜배열의 빈 요소
🎜JavaScript 배열은 빈 요소 🎜. 다음 코드 구문은 정확하며 배열 길이는 3입니다. 🎜rrreee🎜 사람들을 더욱 혼란스럽게 만드는 것은 루프 문이['a',, 'c']
및 를 처리한다는 것입니다. [ 'a', 정의되지 않음, 'c']
는 동일하지 않습니다. 🎜🎜For ['a',, 'c']
, for/in
및 forEach
는 빈 요소를 건너뛰고 for
및 for/of
는 건너뛰지 않습니다. 🎜rrreee🎜['a', 정의되지 않음, 'c']
의 경우 4개의 루프 구문이 동일하며 "a, undefine, c"가 인쇄됩니다. 🎜🎜빈 요소를 추가하는 또 다른 방법이 있습니다: 🎜rrreee🎜한 가지 더, JSON은 빈 요소를 지원하지 않습니다: 🎜rrreee🎜포인트: for/in
및 < 코드 >forEach는 배열의 빈 요소를 "구멍"🎜. 이 문제를 피하려면 forEach
를 비활성화하는 것이 좋습니다.🎜rrreeefunction-this
🎜for
,< code >for/in 및 for/of
는 외부 범위에 this
를 유지합니다. 🎜🎜forEach
의 경우 화살표 함수를 사용하지 않으면 콜백 함수의 this가 변경됩니다. 🎜🎜Node v11.8.0을 사용하여 아래 코드를 테스트하면 결과는 다음과 같습니다. 🎜rrreee🎜포인트: ESLint의 no-arrow-callback
🎜 규칙에 따르면 모든 콜백 함수는 화살표 함수를 사용해야 합니다. 🎜Async/Await 및 Generators
🎜한 가지 더,forEach()
는 Async/Await 및 Generators와 잘 "협력"할 수 없습니다. 🎜🎜forEach
콜백 함수에서 wait를 사용할 수 없습니다: 🎜rrreee🎜 forEach
콜백 함수에서 Yield를 사용할 수 없습니다: 🎜rrreee🎜For for/of</code > 그런 문제는 없습니다:🎜rrreee🎜물론 <code>forEach()
의 콜백 함수를 비동기 함수로 정의하면 오류가 발생하지 않습니다. forEach
순서대로 실행 🎜 , 두통을 비교합니다. 🎜🎜다음 코드는 큰 것부터 작은 것까지 0-9를 인쇄합니다. 🎜rrreee🎜포인트: forEach
에서 aysnc/await 및 생성기를 사용하지 마세요. 🎜결론
🎜간단히 말하면for/of
는 배열을 순회하는 가장 안정적인 방법입니다. for</code보다 더 간결합니다. code> 루프. 그리고 <code>for/in
및 forEach()
만큼 이상한 특수 사례도 많지 않습니다. for/of
의 단점은 인덱스 값을 얻는 것이 불편하고 forEach()
를 호출할 수 없다는 것입니다. > 그런 체인에 있어요. 🎜使用for/of
获取数组索引,可以这样写:
for (const [i, v] of arr.entries()) { console.log(i, v); }
参考
本文采用意译,版权归原作者所有
原文:http://thecodebarbarian.com/for-vs-for-each-vs-for-in-vs-for-of-in-javascript.html
相关免费学习推荐:js视频教程
更多编程相关知识,请访问:编程入门!!
위 내용은 JS의 네 가지 배열 탐색 방법( for , forEach() , for/in, for/of) 간의 차이점의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

Video Face Swap
완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

WebSocket 및 JavaScript를 사용하여 온라인 음성 인식 시스템을 구현하는 방법 소개: 지속적인 기술 개발로 음성 인식 기술은 인공 지능 분야의 중요한 부분이 되었습니다. WebSocket과 JavaScript를 기반으로 한 온라인 음성 인식 시스템은 낮은 대기 시간, 실시간, 크로스 플랫폼이라는 특징을 갖고 있으며 널리 사용되는 솔루션이 되었습니다. 이 기사에서는 WebSocket과 JavaScript를 사용하여 온라인 음성 인식 시스템을 구현하는 방법을 소개합니다.

WebSocket과 JavaScript: 실시간 모니터링 시스템 구현을 위한 핵심 기술 서론: 인터넷 기술의 급속한 발전과 함께 실시간 모니터링 시스템이 다양한 분야에서 널리 활용되고 있다. 실시간 모니터링을 구현하는 핵심 기술 중 하나는 WebSocket과 JavaScript의 조합입니다. 이 기사에서는 실시간 모니터링 시스템에서 WebSocket 및 JavaScript의 적용을 소개하고 코드 예제를 제공하며 구현 원칙을 자세히 설명합니다. 1. 웹소켓 기술

JavaScript 및 WebSocket을 사용하여 실시간 온라인 주문 시스템을 구현하는 방법 소개: 인터넷의 대중화와 기술의 발전으로 점점 더 많은 레스토랑에서 온라인 주문 서비스를 제공하기 시작했습니다. 실시간 온라인 주문 시스템을 구현하기 위해 JavaScript 및 WebSocket 기술을 사용할 수 있습니다. WebSocket은 TCP 프로토콜을 기반으로 하는 전이중 통신 프로토콜로 클라이언트와 서버 간의 실시간 양방향 통신을 실현할 수 있습니다. 실시간 온라인 주문 시스템에서는 사용자가 요리를 선택하고 주문을 하면

WebSocket과 JavaScript를 사용하여 온라인 예약 시스템을 구현하는 방법 오늘날의 디지털 시대에는 점점 더 많은 기업과 서비스에서 온라인 예약 기능을 제공해야 합니다. 효율적인 실시간 온라인 예약 시스템을 구현하는 것이 중요합니다. 이 기사에서는 WebSocket과 JavaScript를 사용하여 온라인 예약 시스템을 구현하는 방법을 소개하고 구체적인 코드 예제를 제공합니다. 1. WebSocket이란 무엇입니까? WebSocket은 단일 TCP 연결의 전이중 방식입니다.

JavaScript 및 WebSocket: 효율적인 실시간 일기 예보 시스템 구축 소개: 오늘날 일기 예보의 정확성은 일상 생활과 의사 결정에 매우 중요합니다. 기술이 발전함에 따라 우리는 날씨 데이터를 실시간으로 획득함으로써 보다 정확하고 신뢰할 수 있는 일기예보를 제공할 수 있습니다. 이 기사에서는 JavaScript 및 WebSocket 기술을 사용하여 효율적인 실시간 일기 예보 시스템을 구축하는 방법을 알아봅니다. 이 문서에서는 특정 코드 예제를 통해 구현 프로세스를 보여줍니다. 우리

JavaScript 튜토리얼: HTTP 상태 코드를 얻는 방법, 특정 코드 예제가 필요합니다. 서문: 웹 개발에서는 서버와의 데이터 상호 작용이 종종 포함됩니다. 서버와 통신할 때 반환된 HTTP 상태 코드를 가져와서 작업의 성공 여부를 확인하고 다양한 상태 코드에 따라 해당 처리를 수행해야 하는 경우가 많습니다. 이 기사에서는 JavaScript를 사용하여 HTTP 상태 코드를 얻는 방법과 몇 가지 실용적인 코드 예제를 제공합니다. XMLHttpRequest 사용

사용법: JavaScript에서 insertBefore() 메서드는 DOM 트리에 새 노드를 삽입하는 데 사용됩니다. 이 방법에는 삽입할 새 노드와 참조 노드(즉, 새 노드가 삽입될 노드)라는 두 가지 매개 변수가 필요합니다.

JavaScript는 웹 개발에 널리 사용되는 프로그래밍 언어인 반면 WebSocket은 실시간 통신에 사용되는 네트워크 프로토콜입니다. 두 가지의 강력한 기능을 결합하면 효율적인 실시간 영상 처리 시스템을 만들 수 있습니다. 이 기사에서는 JavaScript와 WebSocket을 사용하여 이 시스템을 구현하는 방법을 소개하고 구체적인 코드 예제를 제공합니다. 첫째, 실시간 영상처리 시스템의 요구사항과 목표를 명확히 할 필요가 있다. 실시간 이미지 데이터를 수집할 수 있는 카메라 장치가 있다고 가정해 보겠습니다.
