지난 에세이에서 jQuery의 생성자를 분석했습니다. 실제 생성자인 jQuery 개체에는 init의 프로토타입 개체가 jQuery의 프로토타입 개체와 참조 관계를 유지합니다. 인스턴스는 마치 jQuery의 인스턴스인 것처럼 정상적으로 jQuery의 프로토타입 메서드를 호출할 수 있습니다. 비하인드 스토리 생성자 init이 어떻게 작성되는지 살펴보겠습니다.
init: function( selector, context, rootjQuery ) { ... }
이 메소드는 3개의 매개변수를 받아들이고 처음 두 매개변수는 jQuery 메소드에 의해 전달되는 것을 볼 수 있습니다
var jQuery = function( selector, context ) { // The jQuery object is actually just the init constructor 'enhanced' return new jQuery.fn.init( selector, context, rootjQuery ); },
Selector는 원칙적으로 모든 값을 입력할 수 있지만 모든 값이 의미가 있는 것은 아닙니다. 정의되지 않은 DOM 요소, 문자열, 함수, jQuery 객체 및 일반 JavaScript 객체만 유효합니다. 이 매개변수는 일반적으로 채워지지만 없습니다. 작성하지 않으면 오류가 발생합니다
컨텍스트는 실행 컨텍스트 또는 실행 범위로 전달되거나 DOM 요소, jQuery 객체 및 일반 JavaScript 객체 중 하나로 전달될 수 있습니다
매개변수 rootjQuery: document.getElementById()가 검색에 실패할 때 사용되는 문서 객체가 포함된 jQuery 객체, selector는 선택기 표현식이고 지정된 컨텍스트가 없으며 selector는 함수이고 실제로는 $(document)입니다.
다음은 12가지 상황으로 나누어 다양한 매개변수에 따라 하나씩 논의합니다
1.selector를 false로 변환 가능
// Handle $(""), $(null), or $(undefined) if ( !selector ) { return this; }
소스 코드의 주석은 매우 명확하게 작성되었습니다. 이 세 가지 상황에서는 아무런 처리 없이 바로 반환됩니다
2. 매개변수 선택자는 DOM 요소입니다
예: $(문서)
// Handle $(DOMElement) if ( selector.nodeType ) { this.context = this[0] = selector; this.length = 1; return this; }
dom 요소인 이상 노드 유형이 있어야 하며, 이 노드를 jquery 객체의 첫 번째 요소로 변환하고 컨텍스트에 할당합니다. 길이 속성은 jQuery의 프로토타입 속성이며 기본값은 0입니다.
// jQuery 객체의 기본 길이는 0입니다
길이: 0,
여기에 요소가 있으면 길이 속성을 1로 변경합니다. 이 작업을 반환하면 함수 실행 결과가 여전히 jQuery 객체가 되므로 $(document).each()와 같은 체인 호출을 구현할 수 있습니다. 획득된 최종 개체는 {0:document,context:document,length:1....}과 유사합니다. 실제로 DOM 노드를 제외한 모든 상황은 결국 이 형식의 개체가 됩니다. 아라비아 숫자 순서로 정렬되므로 $(selector).get(0) 대신 $(selector)[0] 형식을 사용하여 DOM 객체를 얻을 수 있습니다. 예:
<!doctype html> <html> <head> <title></title> </head> <body> <div></div> <div></div> <div></div> </body> <script src='jquery-1.7.1.js'></script> <script> console.log($('div')); /*[div, div, div, prevObject: jQuery.fn.jQuery.init[1], context: document, selector: "div", constructor: function, init: function…] 0: div 1: div 2: div context: document length: 3 prevObject: jQuery.fn.jQuery.init[1]__proto__: jQuery[0] selector: "div" . */ </script> </html>
3. 매개변수는 특수 문자열 "body"입니다.
문서 개체에는 body 요소가 하나만 있으므로 처리를 위해 별도로 나열됩니다.
// The body element only exists once, optimize finding it if ( selector === "body" && !context && document.body ) { this.context = document; this[0] = document.body; this.selector = selector; this.length = 1; return this; }
여기에는 동시에 충족되어야 하는 세 가지 조건이 있습니다. $('body',document)와 같은 겉보기에 정상적인 작성 방법도 컨텍스트가 없어야 한다는 두 번째 조건이 잘 이해되지 않습니다. 이 상황에서는 "무시"됩니다.”
console.log($('body',document)); /* jQuery.fn.jQuery.init[1] 0: body context: document length: 1 prevObject: jQuery.fn.jQuery.init[1] selector: "body" __proto__: jQuery[0] */
결과는 $('body')와 동일하지만 두 가지 상황으로 처리됩니다. body에는 하나의 컨텍스트만 있고 문서만 가능하기 때문일 수 있습니다. 그렇지 않으면 추가할 필요가 없습니다. 컨텍스트가 문서인지 판단해야 합니다. 세 번째 조건은 document.body가 존재해야 한다는 것을 보장하는 것입니다. 그러면 어떤 상황에서 처음 두 조건이 충족되지만 document.body가 존재하지 않습니까? 첫 번째는 js 코드가 html 코드보다 먼저 로드될 때 초보자가 자주 저지르는 실수입니다. 일반적으로 다음과 같이 작성해야 합니다.
$(함수(){...})
또는
$(document).ready(function(){...})
실제로 이 둘은 동일하며 동일한 메소드를 호출합니다. DOM은 이 부분을 로드하고 나중에 분석합니다. 이를 위해 다음과 같이 테스트 HTML 코드를 만들 수 있습니다.
<!doctype html> <html> <head> <title></title> <script src='jquery-1.7.1.js'></script> <script> $('body') </script> </head> <body> <div></div> <div></div> <div></div> </body> </html>
그런 다음 jQuery 소스 코드에서 선택기, 컨텍스트 및 document.body를 출력합니다
console.log(selector+context+document.body); // The body element only exists once, optimize finding it if ( selector === "body" && !context && document.body ) { this.context = document; this[0] = document.body; this.selector = selector; this.length = 1; return this; }
한 번만 작성했지만 실제로는 4번 실행되었습니다. 마지막 번만 호출한 후의 결과입니다. 이때 처음 두 번은 만족하지만 마지막은 null입니다. . 첫 번째 jQuery 전체 아키텍처에서는 정의되지 않은 내용이 다시 작성되므로 document.body도 null로 다시 작성된다는 점을 기억하세요. 코드를 수정하려고 하면 오류가 발생한다고 나오는데, 그러면 html을 로드하지 않고 실행하는 것을 방지하기 위한 것 같습니다
.네 번째 유형은 위에서 언급한 문자열 상황 이외의 문자열입니다. 다음 글에서 더 많은 상황을 남겨보겠습니다.
위 내용은 이 글의 전체 내용입니다. 모두 마음에 드셨으면 좋겠습니다.