태그 보관물: javascript

javascript

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

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



답변

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

요약해서 말하자면:

사양 부족

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

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

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

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

충돌 확률

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

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

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

성능 오버 헤드

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

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

IE DOM은 엉망입니다

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

보너스 : 브라우저 버그


답변

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

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


답변

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

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

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


답변

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


답변

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

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

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


답변