jQuery는 누구에게나 낯선 것이 아니기 때문에 여기서는 그것이 무엇인지, 무엇을 하는지에 대해 많이 언급하지 않겠습니다. 이 글의 목적은 소스 코드에 대한 간단한 분석을 통해 jQuery의 핵심을 논의하는 것입니다. , jQuery가 JavaScript의 고급 기능을 활용하여 훌륭한 JavaScript 라이브러리를 구축하는 방법을 설명합니다.
1 jQuery 첫 소개
핵심 기능 관점에서 jQuery는 간단하고 일반적인 작업인 쿼리 하나만 수행합니다. 그 구문은 너무 간결하고 명확해서 많은 사람들이 이미 javascript가 무엇인지 모르고 jQuery를 사용해 본 적이 있을 것입니다. 이를 한 단어로 표현하면 단순함과 단순성입니다. 디자인 관점에서 보면 jQuery에서 제공하는 메서드는 정적 메서드와 인스턴스 메서드라는 두 가지 주요 범주로 나눌 수 있습니다. 정적 메서드는 $를 통해 직접 액세스되는 메서드입니다. 이러한 메서드는 일반적으로 DOM 요소에서 작동하지 않지만 ajax 요청 및 문자열에 대한 일부 일반적인 작업과 같은 몇 가지 일반적인 도구를 제공합니다. 확장 메소드를 통해 필요한 구성요소를 작성하십시오. 인스턴스 메소드는 정적 메소드와 다릅니다. jQuery는 $()를 실행하여 jQuery 객체를 생성합니다. 이 객체는 쿼리된 모든 DOM 요소를 배열 메소드에 저장합니다. this 객체의 프로토타입 체인은 이러한 DOM을 작동하기 위한 메서드를 구현합니다. 예를 들어, Each() 메서드는 각 DOM 요소를 탐색하는 데 사용됩니다. 내가 방금 이 객체가 "배열로" 저장되었다고 말한 것을 눈치챌 수도 있습니다. 즉, jQuery로 생성된 객체는 배열이 아닙니다. 그러면 이 객체는 정확히 무엇입니까? 실제로 이 개체는 "jQuery 개체"라고도 알려진 jQuery의 핵심입니다. 따라서 이 글의 초점은 jQuery 객체를 분석하고 논의하는 것입니다.
2 jQuery 객체
일반적으로 jQuery를 다음과 같이 사용합니다:
$('div').each(function(index){ //this ...});
$('div') 이후 실행하면 jQuery 개체가 반환됩니다. Each() 메서드는 이 개체의 DOM 요소를 순회합니다. 먼저 $('div')의 실행 프로세스를 살펴보겠습니다(이 기사의 소스 코드는 jQuery 3.0에서 가져옴). 🎜>
jQuery = function( selector, context ) { return new jQuery.fn.init( selector, context ); }이 방법은 $('div')의 입력 방법입니다. $는 jQuery의 약자로 jQuery('div')와 동일하다고 볼 수 있습니다. 메서드는 단 한 가지 작업만 수행합니다. 즉, jQuery.fn.init는 무엇입니까?
init = jQuery.fn.init = = jQuery.fn;
init.prototype = jQuery.fn;이 문장은 무엇을 의미합니까? 이 문장은 init 메소드의 프로토타입 객체가 jQuery.fn 객체를 가리키도록 만듭니다. ., 그렇다면 jQuery.fn은 도대체 무엇인가요? 계속해서 코드를 살펴보겠습니다.
jQuery.fn = jQuery.prototype = { // The current version of jQuery being used jquery: version, constructor: jQuery, // The default length of a jQuery object is 0 length: 0, // Execute a callback for every element in the matched set. each: function( callback ) { return jQuery.each( this, callback ); }, splice: arr.splice };공간을 절약하기 위해 일부 코드를 생략했습니다. 여기에서 볼 수 있듯이 jQuery.fn은 실제로 jQuery의 프로토타입 개체입니다. 이 프로토타입 개체는 이 개체에 대해 작업할 수 있는 몇 가지 메서드가 있습니다.에 정의되어 있습니다. 이 시점에서 약간 혼란스럽다고 느껴지더라도 걱정하지 마세요. 아이디어를 정리해 보겠습니다. jQuery는 먼저 init 메서드를 정의한 다음 init 프로토타입 개체 프로토타입에 일련의 작업 메서드를 정의합니다. 마지막으로 init 메소드의 인스턴스 객체가 반환됩니다. 따라서 위 프로세스는 다음과 같이 단순화될 수 있습니다(의사 코드 표현):
var init = function(selector,context,root){ //... return this; } init.prototype = { length:0, each:function(callback){ //... }, splice:[].splice } jQuery = function(selector,context,root){ return new init(selector,context,root); }그럼 질문은 왜 jQuery.fn의 메서드가 init 프로토타입에 직접 정의되지 않고 정의되어 있는지입니다. jQuery의 프로토타입 객체에서? 사실 이것의 목적은 jQuery의 쿼리 효율성을 높이기 위한 것입니다. init의 프로토타입 개체에 직접 정의하면 쿼리가 실행될 때마다 이렇게 거대한 프로토타입 개체가 생성됩니다. 이 객체가 jQuery의 프로토타입에 정의된 경우 이 객체는 jQuery가 로드될 때 초기화되고 나중에 $()가 실행될 때마다 항상 메모리에 존재하게 되며 init에서 프로토타입을 가리키기만 하면 됩니다. 매번 동일한 개체를 만드는 대신 이 개체를 사용하세요. 이것이 init 함수에서 반환되는 것을 살펴보겠습니다. 이전 블로그에서 함수의 이 값은 런타임 중에 항상 호출자를 가리킨다고 말했습니다. 위 코드에서는 호출자를 찾을 수 없는 것 같습니다. 이때 new 연산자의 작동 메커니즘을 깊이 이해해야 합니다. 이전 블로그의 new 연산자에 대한 설명을 빌려서 의 실행 프로세스를 수행하겠습니다. new init()은 다음과 같이 분류됩니다:
new init(selector,context,root) = { var obj = {}; obj.__proto__ = init.prototype; init.call(obj,selector,context,root); return typeof result === 'obj'? result : obj; }
위 분해 과정에서 볼 수 있듯이 JavaScript는 new를 통해 인스턴스 객체를 생성할 때 먼저 일반 객체 obj를 생성한 다음 obj의 내부 속성 __proto__를 init의 프로토타입 객체를 가리키므로 obj는 프로토타입 체인이 변경되고 3단계에서는 call 메소드를 사용하여 init()를 호출하므로 init의 this는 여기의 obj 객체를 참조합니다.
init()가 실행된 후 은 일치하는 모든 DOM 개체를 배열 형식으로 이 개체에 저장하고 반환합니다. 즉, obj 개체가 반환되고 new 연산자는 결국 이 obj 객체는 새 인스턴스 객체로 반환됩니다. 따라서 new 연산자가 반환한 인스턴스 객체에는 두 가지 특징이 있습니다. 첫째, DOM 쿼리 결과 세트를 포함하고, 둘째, 프로토타입 체인이 init의 프로토타입을 상속하고 init의 프로토타입이 jQuery.fn 객체를 가리킵니다. 이므로 인스턴스 객체에도 이러한 작업 방법이 있습니다.
jQuery는 쿼리를 실행할 때마다 jQuery 객체를 생성하며 동일한 애플리케이션에서 모든 jQuery 객체는 동일한 jQuery 프로토타입 객체를 공유합니다. 따라서 jQuery 개체는 DOM 쿼리 결과 집합을 포함할 뿐만 아니라 jQuery 프로토타입 개체의 작업 메서드도 상속합니다. 이런 방식으로 쿼리 후 이러한 DOM 요소를 조작하는 메서드를 직접 호출할 수 있습니다. 심플하고 편리하며 실용적인 jQuery의 핵심 아키텍처 디자인입니다!
아직 위의 설명이 이해가 안 되시더라도 걱정하지 마세요. jQuery의 디자인 아이디어에 따라 jDate라는 완전한 작은 프로젝트를 작성했으니 비교하고 이해하실 수 있습니다! jDate 프로젝트가 GitHub에 업로드되었습니다. jDate에서 전체 코드를 볼 수 있습니다. 다른 의견이 있으면 언제든지 토론해 주세요.
jQuery의 3가지 결함
jQuery의 핵심 아키텍처를 분석하면 쿼리가 실행될 때마다 jQuery는 메모리 개체에 복잡한 jQuery를 구축해야 한다는 사실을 알 수 있습니다. , 모든 jQuery 개체가 동일한 jQuery 프로토타입을 공유하지만 jQuery의 쿼리 프로세스는 다양한 일치 식별자와 다양한 브라우저의 호환성을 고려해야 합니다. 따라서 DOM에서 몇 가지 간단한 작업만 수행하는 경우에는 jQuery 대신 기본 메서드인 querySelector를 사용하는 것이 좋습니다. 절충안을 만들고 과용하지 마십시오. jQuery에 달려 있습니다!