javascript_javascript 기술의 for 루프 및 for...in 루프를 배우려면 저를 따르세요.

WBOY
풀어 주다: 2016-05-16 15:31:38
원래의
1044명이 탐색했습니다.

JavaScript가 객체를 반복하는 두 가지 방법을 제공한다는 것은 누구나 알고 있습니다.

  • for 루프
  • for..in 루프

1. for 루프

부적절:

루프될 때마다 배열의 길이를 얻어야 합니다.
종료 조건이 명확해야 합니다.
for 루프에서는 배열 또는 인수 및 HTMLCollection 객체와 같은 배열과 유사한 객체의 값을 반복할 수 있습니다. 일반적인 루프 형식은 다음과 같습니다.

// 次佳的循环
for (var i = 0; i < myarray.length; i++) {
 // 使用myarray[i]做点什么
}

로그인 후 복사

이러한 형태의 루프의 단점은 루프를 수행할 때마다 배열의 길이를 얻어야 한다는 것입니다. 이렇게 하면 특히 myarray가 배열이 아니고 HTMLCollection 객체인 경우 코드 성능이 저하됩니다.

HTMLCollections는 DOM 메서드에서 반환된 개체를 참조합니다. 예:

document.getElementsByName()
document.getElementsByClassName()
document.getElementsByTagName()

DOM 표준 이전에 도입되어 오늘날에도 여전히 사용되고 있는 다른 HTMLCollection이 있습니다. 예:

document.images: 페이지의 모든 이미지 요소
document.links: 모든 태그 요소
document.forms : 모든 양식
document.forms[0].elements : 페이지의 첫 번째 양식에 있는 모든 필드

컬렉션의 문제점은 기본 문서(HTML 페이지)를 실시간으로 쿼리한다는 것입니다. 즉, 컬렉션의 길이에 액세스할 때마다 실시간으로 DOM을 쿼리해야 하며 DOM 작업은 일반적으로 비용이 많이 듭니다.

다음 코드와 같이 값을 반복할 때 배열(또는 컬렉션)의 길이를 캐시하는 것이 좋은 이유는 다음과 같습니다.

for (var i = 0, max = myarray.length; i < max; i++) {
 // 使用myarray[i]做点什么
}

로그인 후 복사

이런 방식으로 이 루프 중에 길이 값을 한 번만 검색할 수 있습니다.

콘텐츠 검색을 위해 반복할 때 HTMLCollection의 캐시 길이는 모든 브라우저에서 2배(Safari3)에서 190배(IE7) 사이로 더 빠릅니다. //이 데이터는 매우 오래된 것으로 보입니다

루프에서 컬렉션을 명시적으로 수정하려는 경우(예: DOM 요소 추가) 상수보다는 길이 업데이트를 선호할 수 있습니다.

단일 var 형식을 사용하면 다음과 같이 루프에서 변수를 꺼낼 수 있습니다.

function looper() {
 var i = 0,
  max,
  myarray = [];
 // ...
 for (i = 0, max = myarray.length; i < max; i++) {
  // 使用myarray[i]做点什么
 }
}
로그인 후 복사

이 형식은 단일 var 형식을 고수하므로 일관성이라는 이점이 있습니다. 단점은 코드를 리팩토링할 때 전체 루프를 복사하여 붙여넣는 것이 약간 어렵다는 것입니다. 예를 들어, 한 함수에서 다른 함수로 루프를 복사하는 경우 i와 max를 새 함수에 도입할 수 있는지 확인해야 합니다(여기서 유용하지 않으면 원래 함수에서 삭제해야 할 가능성이 높습니다). ) 잃다).

루프의 마지막 조정은 i를 아래 표현식 중 하나로 바꾸는 것입니다.

i = i + 1
i += 1
로그인 후 복사

JSLint는 "과도한 까다로움"을 촉진하기 때문에 이 작업을 수행하도록 요청합니다. 이를 무시하면 JSLint의 plusplus 옵션은 false가 됩니다(기본값은 기본값임).

두 가지 변형:

  • 변수 1개가 누락되었습니다(최대값 없음)
  • 0과 비교하는 것이 배열 길이나 01이 아닌 다른 항목과 비교하는 것보다 더 효율적이기 때문에 일반적으로 0까지 카운트다운하는 것이 더 빠릅니다.
//第一种变化的形式:

var i, myarray = [];
for (i = myarray.length; i–-;) {
 // 使用myarray[i]做点什么
}

//第二种使用while循环:

var myarray = [],
 i = myarray.length;
while (i–-) {
 // 使用myarray[i]做点什么
}

로그인 후 복사

이러한 작은 개선 사항은 성능만을 위한 것이며 JSLint는 i-- 사용에 대해 불만을 표시합니다.

2. for…in 루프 - "열거형"이라고도 함

for…in 루프는 객체의 속성이나 배열의 각 요소를 반복하는 데 자주 사용됩니다. for…in 루프의 루프 카운터는 숫자가 아니라 문자열입니다. 여기에는 현재 속성의 이름이나 현재 배열 요소의 인덱스가 포함됩니다. 다음은 몇 가지 예입니다.

객체를 순회할 때 루프 카운터인 변수 i는 객체의 속성 이름입니다.

//使用for..in循环遍历对象属性 
varperson={ 
 name: "Admin", 
 age: 21, 
 address:"shandong" 
}; 
for(var i in person){ 
 console.log(i); 
} 

로그인 후 복사

실행 결과는 다음과 같습니다.

이름

나이

주소

배열을 순회할 때 루프 카운터인 변수 i는 현재 배열 요소의 인덱스입니다.

//使用for..in循环遍历数组 
vararray = ["admin","manager","db"] 
for(vari in array){ 
 console.log(i); 
} 

로그인 후 복사

실행 결과:

0

1

2

그러나 이제는 for..in 루프가 사용하기 매우 쉬운 것 같습니다. 하지만 너무 성급하게 생각하지 마세요. 다음 예를 살펴보세요.

var array =["admin","manager","db"]; 
//给Array的原型添加一个name属性 
Array.prototype.name= "zhangsan"; 
for(var i in array){ 
 alert(array[i]); 
} 
로그인 후 복사

运行结果:

admin

manager

db

zhangsan
咦,奇观了,怎么平白无故的冒出来一个zhangsan
现在,再看看使用 for循环会怎样?

vararray = ["admin","manager","db"]; 
//给Array的原型添加一个name属性 
Array.prototype.name = "zhangsan"; 
for(var i =0 ; i<array.length; i++){ 
 alert(array[i]); 
}; 

로그인 후 복사

运行结果:

admin

manager

db
哦, 现在明白了,for..in循环会把某个类型的原型(prototype)中方法与属性给遍历出来,所以这可能会导致代码中出现意外的错误。为了避免这个问题,我们可以使用对象的hasOwnProperty()方法来避免这个问题,如果对象的属性或方法是非继承的,那么hasOwnProperty() 方法返回true。即这里的检查不涉及从其他对象继承的属性和方法,只会检查在特定对象自身中直接创建的属性。

vararray = ["admin","manager","db"]; 
Array.prototype.name= "zhangshan"; 
for(var i in array){ 
//如果不是该对象自身直接创建的属性(也就是该属//性是原型中的属性),则跳过显示 
 if(array.hasOwnProperty(i)){ 
  alert(array[i]); 
  }
} 
로그인 후 복사

运行结果:

admin

manager

db
另外一种使用hasOwnProperty()的形式是取消Object.prototype上的方法。像这样:

// 对象
var man = {
 hands: 2,
 legs: 2,
 heads: 1
};
for (var i in man) {
 if (Object.prototype.hasOwnProperty.call(man, i)) { // 过滤
  console.log(i, ":", man[i]);
 }
}
로그인 후 복사

其好处在于在man对象重新定义hasOwnProperty情况下避免命名冲突。也避免了长属性查找对象的所有方法,你可以使用局部变量“缓存”它。

var i, hasOwn = Object.prototype.hasOwnProperty;
for (i in man) {
 if (hasOwn.call(man, i)) { // 过滤
  console.log(i, ":", man[i]);
 }
}
로그인 후 복사

严格来说,不使用hasOwnProperty()并不是一个错误。根据任务以及你对代码的自信程度,你可以跳过它以提高些许的循环速度。但是当你对当前对象内容(和其原型链)不确定的时候,添加hasOwnProperty()更加保险些。

格式化的变化(通不过JSLint)会直接忽略掉花括号,把if语句放到同一行上。其优点在于循环语句读起来就像一个完整的想法(每个元素都有一个自己的属性”X”,使用”X”干点什么):

// 警告: 通不过JSLint检测
var i, hasOwn = Object.prototype.hasOwnProperty;
for (i in man) if (hasOwn.call(man, i)) { // 过滤
 console.log(i, ":", man[i]);
}
로그인 후 복사

以上就是介绍了JavaScript提供的两种方式迭代对象:for循环和for...in循环,希望这篇文章对大家的学习有所帮助。

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