DOM / 내장 객체 프로토 타입을 확장하는 것이 나쁜 생각 인 이유는 무엇입니까?


15

JS 개발자 커뮤니티에서 내장 프로토 타입을 확장하는 것이 왜 그렇게 겁나는 지에 대한 결정적인 답을 찾고 있습니다. 나는 한동안 프로토 타입 JS 프레임 워크를 사용 해왔고 나 [1,2,3].each(doStuff)에게는 훨씬 더 우아해 보인다 $.each([1,2,3], doStuff). 나는 그것이 "네임 스페이스 오염"을 야기한다는 것을 알고 있지만 왜 그것이 나쁜 것으로 간주되는지 이해하지 못한다. 또한 내장 프로토 타입 확장과 관련하여 실제 성능 저하가 있습니까? 감사!


1
한 가지이다 for(var ... in ...)프로토 타입 기능도 통과하기 때문에 루프가 엉망.
pimvdb

4
"무슨 겁에 질린"정말?! 좋은 신, 남자 :] 괜찮아?
pixelbobby

답변:


12

프로토 타입과 관련하여 객체를 확장하는 것이 좋지 않은 이유를 잘 설명하는 이 기사 를 읽는 것이 좋습니다 .

요약해서 말하자면:

사양 부족

"시제품 객체"의 노출은 사양의 일부가 아닙니다. [...] 구현이 DOM 레벨 2를 완전히 준수하기 위해 전역 노드, 요소, HTMLElement 등 객체를 노출 할 필요가 없습니다.

호스트 객체에는 규칙이 없습니다

DOM 객체는 호스트 객체입니다. [...] 호스트 객체는 구현에 의존하는 동작으로 이러한 내부 메서드를 구현할 수 있습니다.

[...] 내부 메소드 동작은 구현에 따라 다릅니다. [...] 정의상, 당신은 예측할 수없고 완전히 불규칙하게 행동 할 수있는 무언가로 작업하고 있습니다.

충돌 확률

오늘날 사용중인 방대한 양의 환경에서 특정 속성이 이미 일부 DOM의 일부가 아닌지 알 수 없습니다. [...]

모든 명명 된 양식 컨트롤은 프로토 타입 체인을 통해 상속 된 속성을 숨 깁니다. 양식 요소의 충돌 및 예기치 않은 오류 가능성이 훨씬 높습니다.

접두사 전략을 사용하면 문제를 완화 할 수 있습니다. 그러나 아마도 추가 노이즈가 발생할 것입니다.

성능 오버 헤드

[...] IE 6, 7, Safari 2.x 등과 같은 요소 확장을 지원하지 않는 브라우저에는 수동 개체 확장이 필요합니다. 문제는 수동 확장이 느리고 불편하며 확장 할 수 없다는 것입니다.

[...] 요소 확장을 시작하면 라이브러리 API는 확장 된 요소를 어디에서나 반환해야합니다. 결과적으로 $$와 같은 쿼리 방법은 쿼리의 모든 단일 요소를 확장 할 수 있습니다.

IE DOM은 엉망입니다

이전 섹션에서 볼 수 있듯이 수동 DOM 확장은 엉망입니다. 그러나 IE의 수동 DOM 확장은 훨씬 더 나쁘다 ...]

보너스 : 브라우저 버그


9

또 다른 이유는 코드 가독성 / 유지 보수성입니다. 다른 개발자 (특히 초보자)가 내 코드를 읽고 [0, 1, 2].foo(...)있는 경우 foo 메소드가 무엇인지 또는 문서 / 소스를 찾을 수있는 위치를 모를 수 있습니다. foo는 prototype.js, 사용중인 다른 라이브러리 또는 다른 파일에있는 코드의 다른 부분에 의해 추가 된 언어의 확장입니까, 아니면 그들이 모르는 기본 JavaScript 메소드입니까? 그들은 그것을 찾아야하고 그것을 즉시 찾지 못할 수도있다 (또는 갈등이있는 경우에는 올바른 것을 찾지 못할 수도있다).

jQuery 접근 방식 $.foo(...)을 사용하면 foo 메소드의 네임 스페이스가 정의 / 문서를 찾을 수있는 위치를 알 수 있습니다.


분석법의 출처를 발견하는 것은 독자에게 매우 중요합니다. 비록 실제로 웹 코드를 읽을 때 달러 기호가 검색에 도전하기 때문에 jQuery가 좋은 예라고 생각하지는 않지만 이미 그것이 무엇인지 알지 못합니다.
Simon Feltman

4

기본 문제는 다음과 같습니다. 호환되지 않는 방식으로 프로토 타입을 확장하거나 일반적으로 호출되는 메소드를 다른 결과를 생성하는 방식으로 확장하는 두 개의 도구가있는 경우 ( for...inJavaScript에서 특정 문제임 ) 그들의 정상적인 행동이 깨질까?

기본적으로 전역 변수를 잘못 사용할 때와 동일한 문제입니다. 그 자체로는 아마도 아무 일도 일어나지 않을 것입니다. 그러나 두 개의 분리 가능한 코드 조각이 갑자기 서로 밟을 때 문제가 발생합니다 (그리고 발생할 때 디버깅하는 것이 고통 스럽습니다).

확실히 prototype.js는 꽤 잘 알려져 있으며 대부분의 툴이 그 일을 해결합니다. 마찬가지로 기본 프로토 타입을 확장하는 것이 옳은 경우가 있다고 확신합니다. 그러나 조심스럽게 접근해야합니다.


1

이것이 여전히 더 이상 문제인지 확실하지 않지만 이전 버전의 Internet Explorer에 대한 나의 경험은 때때로 특정 내장 유형을 확장 할 수 없다는 것입니다.


1

여기에는 두 가지 별도의 문제가 있습니다. 첫 번째는 내장 프로토 타입의 일반적인 확장이고 다른 하나는 DOM 프로토 타입의 확장입니다. 내장 프로토 타입 확장에 대한 논쟁 :

  • 잠재적 충돌 : 동일한 소스에서 동일한 속성을 정의하는 서로 다른 소스의 두 가지 코드
  • 부작용 : 루프 에 열거 된 확장 메소드 추가와 같은 확장 Array.prototype또는 Object.prototype노크 효과가있을 수 있음for...in

DOM 프로토 타입을 확장하는 경우에도 위의 잠재적 충돌 주장이 여전히 적용됩니다. 또한 DOM 노드는 호스트 객체이므로 기본 JavaScript 객체의 일반적인 규칙이 적용되지 않습니다. 이들은 본질적으로 자신이 좋아하는 것을 할 수 있으며 합리적인 프로토 타입 객체를 제공하거나 추가 ( "확장") 속성을 허용 할 의무가 없습니다. IE 특히 운동이 바로, 여러 DOM 객체의 속성에 대해 다양한 weirdnesses를 DOM은 IE 9 전에 객체에 대한 더 프로토 타입을 제공하지 않으며 가진 (당신은 요소, 아무것도의 세트를 제공 일반적으로 OK 할당 속성있어 비록 document.expando로를 false.)

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.