익명 함수를 정의하고 jQuery를 인수로 전달하는 이유는 무엇입니까?


99

backbone.js 스크린 캐스트에서 훌륭한 peepcode 데모 코드를 살펴보고 있습니다. 그 안에 백본 코드는 모두 jQuery 객체를 전달하는 익명 함수로 묶여 있습니다.

(function($) {
  // Backbone code in here
})(jQuery);

내 백본 코드에서 jQuery DOM 'ready'이벤트에 모든 코드를 래핑했습니다.

$(function(){
  // Backbone code in here
});

첫 번째 접근 방식의 요점 / 장점은 무엇입니까? 이렇게하면 jQuery 객체가 함수 인수로 전달되는 즉시 실행되는 익명 함수가 생성되어 $가 jQuery 객체임을 효과적으로 보장합니다. 이것이 유일한 요점입니까-jQuery가 '$'에 바인딩되어 있는지 확인하거나이를 수행하는 다른 이유가 있습니까?


4
대신 SO를 먼저 검색해야합니다.
Alexander

다른 라이브러리와의 상호 운용성-페이지 작성자가를 사용해야 $.noConflict()하는 경우 첫 번째 예제는 계속 작동합니다.
DCoder

중복 가능성 : jQuery 및 $ 질문
Alexander

차이점에 대한 가능한 중복 jQuery document.ready 대 자체 호출 익명 함수 참조
Bergi

@Alexander 그러나 다른 사람들은 먼저이 질문을 찾을 것입니다. :-)
caiosm1005

답변:


183

여러분이 보여준 두 개의 코드 블록은 실행시기와 이유가 크게 다릅니다. 그들은 서로 배타적이지 않습니다. 그들은 동일한 목적을 제공하지 않습니다.

자바 스크립트 모듈


(function($) {
  // Backbone code in here
})(jQuery);

이것은 즉시 호출 함수로 구현 된 "JavaScript 모듈"패턴입니다.

이 코드의 목적은 "모듈화", 개인 정보 보호 및 코드 캡슐화를 제공하는 것입니다.

이 구현은 호출하는 (jQuery)괄호에 의해 즉시 호출되는 함수입니다 . jQuery를 괄호 안에 전달하는 목적은 전역 변수에 로컬 범위를 제공하는 것입니다. 이것은 $변수 를 찾는 오버 헤드의 양을 줄이는 데 도움이되며 경우에 따라 축소 자에 대한 더 나은 압축 / 최적화를 허용합니다.

즉시 호출하는 함수가 즉시 실행됩니다. 함수 정의가 완료되는 즉시 함수가 실행됩니다.

jQuery의 "DOMReady"기능

이것은 jQuery의 "DOMReady"함수에 대한 별칭입니다 : http://api.jquery.com/ready/


$(function(){
  // Backbone code in here
});

jQuery의 "DOMReady"함수는 DOM이 JavaScript 코드에 의해 조작 될 준비가되면 실행됩니다.

백본 코드의 모듈 대 DOMReady

jQuery의 DOMReady 함수 내에 백본 코드를 정의하는 것은 잘못된 형식이며 잠재적으로 애플리케이션 성능을 손상시킵니다. 이 함수는 DOM이로드되고 조작 할 준비가 될 때까지 호출되지 않습니다. 즉, 개체를 정의하기 전에 브라우저가 DOM을 한 번 이상 파싱 할 때까지 기다립니다.

DOMReady 함수 외부에서 Backbone 개체를 정의하는 것이 더 좋습니다. 저는 다른 많은 사람들 중에서 JavaScript 모듈 패턴 내에서이 작업을 수행하여 코드에 대한 캡슐화 및 개인 정보 보호를 제공하는 것을 선호합니다. 저는 "Revealing Module"패턴 (위의 첫 번째 링크 참조)을 사용하여 모듈 외부에서 필요한 비트에 대한 액세스를 제공하는 경향이 있습니다.

DOMReady 함수 외부에서 개체를 정의하고 개체를 참조 할 수있는 방법을 제공함으로써 브라우저가 JavaScript 처리를 앞당기 고 잠재적으로 사용자 경험을 가속화 할 수 있습니다. 또한 물건을 움직일 때 더 많은 DOMREady 함수를 만드는 것에 대해 걱정할 필요없이 물건을 움직일 수 있기 때문에 코드를 더 유연하게 만듭니다.

Backbone 객체를 다른 곳에 정의하더라도 여전히 DOMReady 함수를 사용할 것입니다. 그 이유는 많은 Backbone 앱이 어떤 방식 으로든 DOM을 조작해야하기 때문입니다. 이렇게하려면 DOM이 준비 될 때까지 기다려야하므로 DOMReady 함수를 사용하여 정의 된 후 애플리케이션을 시작해야합니다.

웹에서 이에 대한 많은 예제를 찾을 수 있지만 다음은 Module 및 DOMReady 함수를 모두 사용하는 매우 기본적인 구현입니다.



// Define "MyApp" as a revealing module

MyApp = (function(Backbone, $){

  var View = Backbone.View.extend({
    // do stuff here  
  });

  return {
    init: function(){
      var view = new View();
      $("#some-div").html(view.render().el);
    }
  };

})(Backbone, jQuery);



// Run "MyApp" in DOMReady

$(function(){
  MyApp.init();
});

1
자세한 답변에 감사드립니다. 나는 DOMReady 이벤트가 발생했을 때만 호출되는 DOMReady 함수에 대해 알고 있었지만 이것이 문제가 될 것이라고는 생각하지 못했습니다. 분할 실제로 가장 좋은 방법처럼 보인다 DOM을 준비 그들과 상호 작용 다음 모듈 내부 백본 비트를 정의하고,에 코드
매트 로버츠

2
흥미롭게도 백본 src가있는 "todo"예제 앱은 모든 것을 dom에 준비합니다.
Matt Roberts

2
자바 스크립트 모듈 패턴은 IIFE.
Jess

1
익명 함수는 본질적으로 DOM 준비와 동시에 실행되므로 어떻게 더 효율적으로 만들 수 있습니까 ??
bhavya_w 2014 년

14

부수적으로 $를 익명 함수에 대한 인수로 보내면 $ 함수가 많이 호출되는 경우 약간의 긍정적 인 성능 영향을주는 해당 함수에 $ 로컬이됩니다. 이는 자바 스크립트가 변수에 대한 로컬 범위를 먼저 검색 한 다음 창 범위 ($가 일반적으로있는 곳)까지 아래로 이동하기 때문입니다.


9

사용 된 경우에도 해당 클로저 내부에서 항상 사용할 수 있습니다 .$$.noConflict()

이 폐쇄가 없으면 전체 시간 jQuery대신 사용해야 합니다 $.



2

둘 다 사용하십시오.

라이브러리 충돌을 방지하고 $로 예상 한대로 jQuery를 사용할 수 있는지 확인하기 위해 jQuery를 전달하는 자체 호출 함수입니다.

DOM이로드 된 후에 만 ​​javascript를 실행하는 데 필요한 .ready () 바로 가기 메서드 :

(function($) {
    $(function(){
          //add code here that needs to wait for page to be loaded
    });

    //and rest of code here
})(jQuery);

내가 SO의 다른 곳에서 찾은 더 짧은 버전 (또한 정의되지 않은 보호) :jQuery(function ($, undefined) { /* Code */ });
Jared Gotte
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.