JavaScript 프레임 워크 / 라이브러리에 순수 JavaScript에 이미 존재하는 함수가있는 이유는 무엇입니까?


60

프레임 워크 / 라이브러리가 기본적으로 존재하지만 왜 자신의 도우미가 있는지 궁금합니다.

jQueryAngularJS를 보자 . 자체 each반복자 기능이 있습니다.

그러나 우리는 있습니다 Array.prototype.forEach.

비슷하게,

그러나 우리는 JSON.parse()바닐라 JavaScript 기능을 가지고 있습니다 .


75
웹 개발의 나쁜 시절을 기억하는 사람으로서,이 질문은 나를 울게합니다.
josh3736

3
@ josh3736 최소한 IE6를 지원할 필요는 없습니다 ( '아마도 "만약 그것이 작동하고 쓰레기처럼 보일 수 있습니다")
Izkata

12
jQuery.each그리고 Array.prototype.forEach해당되지 않습니다.
zzzzBov

3
vanillaJS에서 발견 된 기능 중 얼마나 많은 것이 jQ와 같은 툴킷에서 비롯된 것입니까? 대답은 : many 입니다. 이것은 왜 우리에게 아직도 그것들을 사용하고 있습니까? 왜 jQuery를 포함 $.each하고 네이티브 (및 더 빠른)를 사용하지 Array.prototype.forEach않습니까?
Elias Van Ootegem

1
@ josh3736 괜찮아 ... i.stack.imgur.com/HJs4V.jpg
Crono

답변:


93

해당 라이브러리가 작성되었을 때 일부 주요 브라우저는 해당 기능을 지원하지 않았습니다. 일단 작성하여 사용하면 많은 응용 프로그램을 중단하지 않고 이러한 기능을 이러한 라이브러리에서 제거 할 수 없습니다.

(이 경우 "주요 브라우저"는 여전히 많은 사용자가 최신 버전으로 업그레이드 할 필요가없는 Internet Explorer와 같은 이전 버전의 브라우저를 포함하여 여전히 시장 점유율이 큰 브라우저를 의미합니다.


44
$ ( 'marquee'). each (function () {$ (this) .append ($ ( '<bgsound />', {src : "good-answer.mp3"}));});
Pierre Arlaud

36
@dirkk 최근 브라우저가 지원하지 않는 것은 아닙니다. 모든 사람이 최신 브라우저를 사용하는 잠재 고객을 보유 할만큼 운이 좋은 것은 아닙니다.
George Reith

14
Array.prototype.forEach배열에 대해서만 반복-라이브러리 반복자 함수는 배열 또는 객체에 대해 반복 할 수 있습니다.
JoeG

3
함수는 구식 브라우저를 지원하고 라이브러리를 호출하는 구식 코드를 지원하기 위해 존재하며 프로그래머는 다시 작성하기를 원하지 않습니다. IE 6에 대한 지원을 중단하더라도 고대의 IE 사본을 지원해야 할 때 JavaScript가 사용 중일 수 있습니다.
Michael Shopsin

6
이 함수 중 많은 것들 (예 : jQuery.parseJSON ())은 브라우저가이를 지원하는지 확인한 다음 브라우저 메소드로 설정하고 호환되지 않는 브라우저에서만 사용할 수 있습니다!
Josef

35

브라우저마다 브라우저마다 구현 및 기능이 다르기 때문에 JavaScript 엔진에서 구워졌습니다. 동일한 "vanilla-JS"코드는 두 개의 다른 브라우저 또는 동일한 브라우저의 두 가지 버전에서 다르게 실행될 수 있습니다.

널리 사용되는 JS 라이브러리에서 제공하는 추상화 계층이이 문제를 해결하는 방법입니다. 배후에서 다양한 브라우저 용량 및 제한 사항을 해결하고 그 위에 통합되고 사용하기 쉬운 API를 제공합니다. 이를 통해 DOM 객체 가져 오기 또는 JSON 데이터 가져 오기와 같은 일반적인 작업을 일관되고 효율적이며 브라우저와 무관하게 수행 할 수 있습니다.

따라서 브라우저 X 또는 Y에서 작동하도록 코드를 작성하는 방법이 아니라 코드를 작성하는 데 집중할 수있는 개발자가 훨씬 쉽게 생활 할 수 있습니다.


2
"core JS"의 동작은 모든 브라우저에서 올바르게 지정되고 테스트되었습니다.
Domenic

2
@Domenic Syntax 이외에도 자바 스크립트 구현은 브라우저마다 다릅니다. 몇 가지 브라우저에서만 또는 때로는 하나의 브라우저에서만 찾을 수있는 속성, 메서드, 이벤트 및 기능이 있습니다.
Crono

1
예, 브라우저에는 비표준 기능이 있습니다. 그것은이 질문에서 논의 된 표준 기능과 아무 관련이 없습니다.
Domenic

8
@Domenic "질문에 설명 된 표준 기능"이 Array.prototype.forEachJSON.parse기능 을 의미하는 경우 Google에서 빠른 검색을 수행하면 잘못되었음을 알 수 있습니다. JSONIE7에서는 개체가 지원 forEach되지 않았으며 일부 Opera 버전에서는 정의되지 않았습니다. 그러나 jQuery와 같은 라이브러리는 이러한 제한 사항에 대해 알고 있었고 이러한 문제를 해결했습니다. 그래서 나는 내 대답이 옳다고 생각합니다.
Crono

27

1. 이전 버전과의 호환성

JavaScript는 ECMAScript 의 구현입니다 . 이러한 기능의 대부분은 ECMAScript 5 (ES5)에 도입되었지만 여전히 시장 점유율이 상당히 높은 많은 구형 브라우저는 이러한 기능을 지원하지 않습니다 ( ECMAScript 5 호환성 표 참조 ).

일반적으로 라이브러리는 고유 한 폴리 필을 사용하는 경우 기본 구현으로 되돌아갑니다 (예 : AngularJS의 구현 ( angular.js L203-257 ) 참조 ).

function forEach(obj, iterator, context) {
  var key;
  if (obj) {
    if (isFunction(obj)){
      for (key in obj) {
        // Need to check if hasOwnProperty exists,
        // as on IE8 the result of querySelectorAll is an object without a hasOwnProperty function
        if (key != 'prototype' && key != 'length' && key != 'name' && (!obj.hasOwnProperty || obj.hasOwnProperty(key))) {
          iterator.call(context, obj[key], key);
        }
      }
    } else if (obj.forEach && obj.forEach !== forEach) {
      obj.forEach(iterator, context);
    } else if (isArrayLike(obj)) {
      for (key = 0; key < obj.length; key++)
        iterator.call(context, obj[key], key);
    } else {
      for (key in obj) {
        if (obj.hasOwnProperty(key)) {
          iterator.call(context, obj[key], key);
        }
      }
    }
  }
  return obj;
}

다음 행은 forEach메소드가 오브젝트에 존재하는지 여부와 AngularJS 버전인지 여부를 확인합니다. 그렇지 않은 경우 이미 지정된 기능 (기본 버전)을 사용합니다.

} else if (obj.forEach && obj.forEach !== forEach) {
  obj.forEach(iterator, context);
}

2. 편의

네이티브 JavaScript Array.prototype.forEach에서의 인스턴스 전용 메소드 Array이지만 대부분 의 클래스 Object도 반복 가능합니다.

이러한 이유로 많은 라이브러리 제작자는 함수를 다형성으로 만듭니다 (여러 유형을 입력으로 받아 들일 수 있음). 위의 AngularJS 코드를 가져 와서 어떤 입력을 받아들이는지 봅시다 :

기능 :

if (isFunction(obj)){
  for (key in obj) {
    // Need to check if hasOwnProperty exists,
    // as on IE8 the result of querySelectorAll is an object without a hasOwnProperty function
    if (key != 'prototype' && key != 'length' && key != 'name' && (!obj.hasOwnProperty || obj.hasOwnProperty(key))) {
      iterator.call(context, obj[key], key);
    }
  }

배열 (각각 forEach 지원) :

} else if (obj.forEach && obj.forEach !== forEach) {
  obj.forEach(iterator, context);

Array (기본적으로 forEach를 지원하지 않음), String, HTMLElement, 유효한 길이 속성을 가진 Object를 포함한 배열 과 유사한 객체 :

} else if (isArrayLike(obj)) {
  for (key = 0; key < obj.length; key++)
    iterator.call(context, obj[key], key);

사물:

} else {
  for (key in obj) {
    if (obj.hasOwnProperty(key)) {
      iterator.call(context, obj[key], key);
    }
  }
}

결론

보시다시피 AngularJS는 대부분의 JavaScript 객체를 반복하지만 기본 함수와 동일한 방식으로 작동하지만 훨씬 더 다양한 유형의 입력을 허용하므로 라이브러리에 유효한 추가 기능뿐만 아니라 ES5 함수를 가져 오는 방법입니다 레거시 브라우저로


2
나중에 변경 되면 나중에 참조 할 수 있도록 특정 커밋 (예 : angular.js L203-257 ) 을 가리 키도록 링크를 업데이트 할 수 있습니다 master.
Whymarrh
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.