2011-05-09 4 views
2

for-in 컨트롤 블록을 사용할 때 javascript 객체의 기본 제공 속성이 반복되지 않는 이유는 무엇입니까?Javascript for 및 내장 속성

예를 들어 :

var y = 'car'; 
for (var j in y) 
{ 
    console.log(j); 
} 

인쇄됩니다

0 
1 
2 

을 String.prototype 등 길이, 교체, 문자열, 속성을 가지고 있지만

프로토 타입을 확장하는 경우, 그러나 , 모든 새 속성 반복됩니다.

인쇄됩니다 :

0 
1 
2 
foo 
+0

FYI : JavaScript 속성에 대한 반복 순서는 정의되지 않았습니다. 많은 구현체는 정의 된 순서대로 속성을 반환 할 것이고 다른 것들 (정확하게 기억한다면 Opera와 Safari의 버전)은 순서가 틀릴 수 있습니다. – mikerobi

+0

@mikerobi : Chrome은 다른 브라우저와 동일한 순서로 반복하지 않기 위해 [잘 알려져 있습니다] (http://code.google.com/p/chromium/issues/detail?id=883). –

+0

@Andy E, 오래된 문제인데 사용 된 모든 Chrome 버전이 정의 순서대로 반복되었습니다. 반복으로 많은 개발자가 결함 코드를 작성하게됩니다. 작동하는 것처럼 보이지만 예기치 않게 언제든지 중단 될 수있는 코드는 작동하지 않는 코드보다 훨씬 위험합니다. – mikerobi

답변

3

기본적으로 내장 된 속성 내부적으로 "비 열거"로 표시됩니다. 이것은 자연적으로 열거되지 않았 음을 의미합니다.

편집 : 앤디는 친절하게 지적했듯이, 당신은defineProperty를 사용하여 자바 스크립트의 현재 버전에 enumerable : false을 설정할 수 있습니다 . 그러나 이것은 Opera를 전혀 지원하지 않는 것 같습니다. IE 8은 DOM 객체에서만 지원하며 Safari는 이 아닌 -DOM 객체 (브라우저 지원을 위해 파일 아래쪽을보십시오)에서만 지원합니다.

이 모든 브라우저 간 재미는 일관된 브라우저 지원이 필요한 경우이 동작에 의존해서는 안된다는 것을 의미합니다.

Object.defineProperty(String.prototype, "foo", {value : 7, enumerable : false}); 

당신은 실제로 enumerable : falsedefineProperty를 호출 할 때 기본적으로 false 인을 포함 할 필요가 없습니다 : 여기

는 비 열거 속성을 정의 할 수있는 방법입니다.

+3

끝 부분이 잘못되었습니다. ECMAScript/JavaScript의 현재 버전은'defineProperty'와'defineProperties'라는 메소드를 가지고 있는데, 무엇보다도'enumerable : false'를 설정할 수 있습니다. –

+1

@Andy : 수정 해 주셔서 감사합니다. –

3

내부 ECMAScript DontEnum attribute이 설정되어 있는지 여부를 나타내는 부울을 반환하는 propertyIsEnumerable 메서드가 있습니다 (구현 중 끔찍한 불일치에 유의하십시오). 위와 같이 DontEnum을 설정할 수는 없으며 propertyIsEnumerable을 통해서만 쿼리 할 수 ​​있습니다.

var y = 'car'; 
for (var j in y) { 
    console.log(j); 
} 

에서

2

당신은 문자의 배열로 처리됩니다 String 인스턴스의 속성을 통해 반복된다. 이 경우 배열에는 3 개의 요소가 있으므로 '속성'은 0, 1, 2입니다. console.loggedy[j] 인 경우 'c','a','r'을 확인해야합니다.

for (var j in y.constructor.prototype) 
{ 
    console.log(j); 
} 

String.prototype.foo = 7; 
var y = 'car'; 
for (var j in y) { 
    console.log(j); 
} 

에서는 속성을 추가 : 이제 프로토 타입 속성/메소드를보고 싶다면

, 당신은 (String이다) Y의 constructor 프로토 타입의 프로토 타입을 조회한다 foo ~ String.prototype. 생성자 (String) 프로토 타입에 속성을 추가하면 모든 인스턴스에서 사용할 수 있습니다. 문자 리터럴 yString의 인스턴스이므로 fooy에 표시되며 속성을 통해 열거됩니다.

은 참조 : this SO question

1

모두에 확장하기를 elses false로 기본적으로 이러한 속성은 그래서 당신은 단지 포함 할 수없는 Object.defineProperty

var o = {}, 
    def = Object.defineProperty; 

def(o, "myProperty", { 
    "value": 42, 
    "enumerable": false, 
    "writeable": true, 
    "configurable": true 
}); 

주를 사용하여이 아닌 열거로 자신의 속성을 표시 할 수 있습니다 답변 "enumerable"을 사용하여 false로 설정하십시오.