Javascript에서 for 루프의 여러 사용법 비교 및 ​​성능 향상 방법

伊谢尔伦
풀어 주다: 2018-05-18 15:45:02
원래의
3658명이 탐색했습니다.

for 루프는 js에서 객체나 배열을 탐색할 때 유용합니다. for 루프의 몇 가지 사용 예를 살펴보겠습니다.

일반적인 작성 방법은 다음과 같습니다.

for(var i = 0;i< arr.length;i++) {
 var a = arr[i];
 //...
 }
로그인 후 복사

양수 시퀀스 루프가 있는 일반적인 for 루프입니다. 이런 식으로 작성하는 것의 단점은 누구나 알고 있습니다. arr에서 길이를 가져와서 매번 i와 비교하는 것은 성능 낭비입니다(그리고 arr의 길이가 동적으로 변경되면 무한 루프가 발생합니다). 이 루프를 개선하는 방법은 변수를 사용하여 arr.length를 저장하는 것입니다. arr.length

for(var i = 0, al = arr.length;i< al;i++) {
 var a = arr[i];
 //...
 }
로그인 후 복사

这样比第一种可以略微提升点性能,要是数组长,可以提升更多。

不过这样写就多了个变量al,且这个变量只在用来与i对比的时候有用,看着有点鸡肋。

如果循环顺序对你不重要,那你可以尝试倒序循环:

for(var i = arr.length-1;i > -1;i--) {
 var a = arr[i];
 //...
 }
로그인 후 복사

这样一来变量少些,且还缓存过arr长度,性能也不错。但这里的代码写得有点拙劣(我故意的),首先是i = arr.length-1(居然要-1,靠),然后是循环继续执行的条件i > -1,都让有洁癖的人无法忍受。

下面是我常用的倒序for循环写法:

for(var i = arr.length;i--;) {
 var a = arr[i];
 //...
 }
로그인 후 복사

这已经非常精简了。原理需要理解一下:for循环继续执行的条件,是;;之间的这个判断要为真,而这里的i–,在第一次循环进来的时候,i=arr.length,i–值不变(为什么不变?因为要在for循环体里面,才会发现i变了);当i=1时,i- -还是1,但进入循环体后,就是0了,所以可以正常执行最后一次循环;当i=0时,i–还是0,而0已经不为真了,所以循环就不会继续执行了。

大家注意到上面的所有代码的for循环体里,都有个var a = arr[i] ,用来取出当前循环到的数组项。这实际上也是种浪费,且jsLint等会告诉你:不要在循环里声明变量。。。

倒序的for可以精简至斯,但我就是要正序,而且要效率高,变量少,怎么办?

如下:

for(var i = 0, a;a = arr[i++];) {
 //...
 }
로그인 후 복사

这种写法好处在于:几乎不可避免的arr.length不见了,前面说的取出当前循环到的数组项的那一句也不见了。

原理:

a = arr[i++] ,在这里作为循环能执行的条件,注意这里只有一个=号,所以这不是判断句,是赋值语句,就是把arr[i++]赋给a,然后判断a是不是真值。i++与i–的原理类型我就不说了,只说当i++已经超过数组的长度时,循环肯定要停止才行,而这里真的就停止了,为什么?因为a=arr[i++] rrreee

이는 첫 번째 방법에 비해 성능을 약간 향상시킬 수 있으며, 배열이 길면 더욱 향상될 수 있습니다.

하지만 이렇게 작성하면 추가 변수 al이 추가되는데, 이 변수는 i와 비교할 때만 유용하며 약간 쓸모없어 보입니다.

루프 순서가 중요하지 않다면 역순 루프를 시도해 볼 수 있습니다.


rrreee

이렇게 하면 변수가 더 적고 arr 길이가 캐시되며 성능도 좋습니다. 하지만 여기 코드는 약간 잘못 작성되었습니다(저는 의도적으로 했습니다). 먼저 i = arr.length-1(실제로는 -1이 필요합니다), 그리고 루프 조건을 지정합니다. 계속 실행하려면 i > - 1. 그것들은 모두 결절공포증이 있는 사람들에게는 참을 수 없는 일입니다.


다음은 제가 일반적으로 사용하는 루프 작성 방법의 역순입니다.

rrreee

이것은 이미 매우 간소화되었습니다. 원칙을 이해해야 합니다. for 루프가 계속 실행되기 위한 조건은;; 사이의 판단이 참이어야 한다는 것입니다. 여기서 첫 번째 루프가 들어올 때 i=arr.length code >, i- 값은 변경되지 않고 유지됩니다(왜 변경되지 않은 채 유지됩니까? for 루프 본문에서 i가 변경되었음을 알아야 하기 때문에 i=1일 때 i- -는 여전히 1이지만 루프 본문에 들어간 후에는 , 0이므로 마지막 루프는 정상적으로 실행될 수 있습니다. i=0일 때 i–는 여전히 0이고 0은 더 이상 참이 아니므로 루프는 계속 실행되지 않습니다.

위의 모든 코드의 for 루프 본문에는 현재 루프에 연결된 배열 항목을 꺼내는 데 사용되는 var a = arr[i] 가 있다는 것을 모두가 알아차렸습니다. 이것은 실제로 낭비이며 jsLint와 다른 사람들은 다음과 같이 말할 것입니다. 루프에서 변수를 선언하지 마십시오. . .

for 역순을 이렇게 단순화할 수 있는데 정순순만 원하고 효율적이고 변수가 적어야 합니다. 어떻게 해야 하나요?

    는 다음과 같습니다.
  1. rrreee

    이런 작성 방식의 장점은 거의 불가피한 arr.length가 누락되었다는 점이며, 위에서 언급한 현재 루프된 배열 항목을 꺼내는 문장도 없어진.

  2. 원리:

  3. a = arr[i++] 는 루프가 실행되기 위한 조건으로 사용됩니다. 여기에는 = 기호가 하나만 있으므로 이는 a가 아닙니다. 판단문이지만 a에 대입문, 즉 arr[i++]를 대입하여 a가 참값인지 판단합니다. i++ 및 i–의 기본 유형에 대해서는 다루지 않겠습니다. i++가 배열의 길이를 초과하면 루프가 중지되어야 하며 실제로 여기서 중지된다는 점만 말씀드리겠습니다. a=arr[i++] 때문에 배열 자체의 길이를 초과하는 항목을 얻으면 정의되지 않은 값만 얻게 되고, 정의되지 않은 것은 false 값이 되어 루프 조건이 실패하게 됩니다.

물론 이런 방식으로 작성하는 것의 단점도 분명합니다.


1. arr의 길이가 동적으로 변경되면 무한 루프가 여전히 발생합니다. 왜냐하면 우리는 arr.length를 캐시한 적이 없기 때문입니다.


2. 루프가 숫자 배열인 경우 꺼낸 항목(즉, a의 값)이 0이면 루프가 종료됩니다(0은 거짓 값이므로).

3. 배열의 항목이 false 값(빈 문자열, 0, null, 정의되지 않음 포함)인 경우 루프도 종료됩니다.🎜🎜따라서 이 작성 방법을 사용할 때는 위 항목을 제외하는 것이 가장 좋습니다. 상황. 🎜🎜이 원리는 역순 루프에도 사용될 수 있습니다. 🎜🎜🎜모두를 위한 몇 가지 마지막 조언: 🎜🎜🎜🎜🎜코드 간소화가 높은 효율성을 의미하지는 않습니다!🎜🎜🎜🎜고의적으로 코드를 간소화하기 위해 성능을 잃지 마세요🎜🎜🎜🎜🎜그런데, 여기 for 루프의 성능을 향상시키기 위한 몇 가지 포인트는 다음과 같습니다.🎜 🎜🎜 1. 적절한 시점에 중단하세요! 모든 것을 순회할 필요가 없다면 중단 조건을 추가해야 합니다! 🎜🎜🎜 2. for 루프 본문에 변수를 선언하지 마세요(var는 한 번 사용하고 값을 여러 번 할당하는 것이 좋습니다) 🎜🎜🎜 2. 배열 길이를 캐시하고 변수를 최대한 적게 사용합니다 🎜

위 내용은 Javascript에서 for 루프의 여러 사용법 비교 및 ​​성능 향상 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿