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
i = arr.length-1
(실제로는 -1이 필요합니다), 그리고 루프 조건을 지정합니다. 계속 실행하려면 i > - 1. 그것들은 모두 결절공포증이 있는 사람들에게는 참을 수 없는 일입니다. 이것은 이미 매우 간소화되었습니다. 원칙을 이해해야 합니다. 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 역순을 이렇게 단순화할 수 있는데 정순순만 원하고 효율적이고 변수가 적어야 합니다. 어떻게 해야 하나요?
이런 작성 방식의 장점은 거의 불가피한 arr.length
가 누락되었다는 점이며, 위에서 언급한 현재 루프된 배열 항목을 꺼내는 문장도 없어진.
a = arr[i++]
는 루프가 실행되기 위한 조건으로 사용됩니다. 여기에는 = 기호가 하나만 있으므로 이는 a가 아닙니다. 판단문이지만 a에 대입문, 즉 arr[i++]
를 대입하여 a가 참값인지 판단합니다. i++ 및 i–의 기본 유형에 대해서는 다루지 않겠습니다. i++가 배열의 길이를 초과하면 루프가 중지되어야 하며 실제로 여기서 중지된다는 점만 말씀드리겠습니다. a=arr[i++]
때문에 배열 자체의 길이를 초과하는 항목을 얻으면 정의되지 않은 값만 얻게 되고, 정의되지 않은 것은 false 값이 되어 루프 조건이 실패하게 됩니다. 물론 이런 방식으로 작성하는 것의 단점도 분명합니다.
1. arr의 길이가 동적으로 변경되면 무한 루프가 여전히 발생합니다. 왜냐하면 우리는 arr.length를 캐시한 적이 없기 때문입니다.
2. 루프가 숫자 배열인 경우 꺼낸 항목(즉, a의 값)이 0이면 루프가 종료됩니다(0은 거짓 값이므로).
위 내용은 Javascript에서 for 루프의 여러 사용법 비교 및 성능 향상 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!