한동안 jQuery를 사용해 왔지만 실제로 파악하기 어려운 API 구현이 몇 가지 있습니다. 편집자는 관련 소스 코드를 참조하고 이제 나의 학습 과정과 성과를 모든 사람과 공유합니다.
다음은 jQuery의 구현 아이디어를 중심으로 단순화된 코드를 사용하여 소개하겠습니다~>_<~
//匿名立即执行函数 //.防止污染全局空间 //.选择性保护内部变量 (function(window, undefined){ //第二参数undefined设置而不传的原因: // 外部发生这种情况:var undefined = 时,undefined会被篡改 // 设置第二参数而不传,则undefined就会被重置回原来值 function jQuery(sel){ return new jQuery.prototype.init(sel); } jQuery.prototype = { constructor: jQuery, init: function(sel){ if(typeof sel === 'string'){ var that = this; //jQuery内部使用的是Sizzle,这里使用querySelectorAll替代 var nodeList = document.querySelectorAll(sel); Array.prototype.forEach.call(nodeList, function(val, i){ that[i] = val; }) this.selector = sel; this.length = nodeList.length; } } } jQuery.prototype.init.prototype = jQuery.prototype; //对外暴露jQuery:将jQuery绑定在window上面 window.$ = jQuery; })(window);
---------------
jQuery는 처음에 익명의 즉시 실행 기능으로 내부를 래핑하고 5행에서 외부에 노출합니다.
소위 익명 즉시 실행 함수는 이 함수가 익명(이름 없음)이며 정의된 후 즉시 호출된다는 의미입니다.
$("div")를 외부에서 호출하면 실제로는 내부 jQuery("div")를 호출합니다.
(function(window, undefined){ //内部变量 //对外暴露jQuery:将jQuery绑定在window上面 window.$ = jQuery; })(window); $("div")
---------------
자, 좀 더 복잡해 보겠습니다. 다음 코드는 주로 그림과 같이 상호 참조를 구현합니다.
$('div') 호출을 예로 들어보겠습니다.
코드의 두 번째 줄에서 볼 수 있듯이 jQuery는 jQuery.prototype.init를 사용하여 jQuery 개체를 인스턴스화하지만 이로 인해 문제가 발생합니다.
인스턴스화된 개체는 init 아래의 변수에만 액세스할 수 있으며 jQuery.prototype에는 액세스할 수 없습니다(jQuery에서 제공하는 API가 이 개체에 바인딩됨).
그러므로 21번째 코드 줄을 작성하고 init.prototype을 jQuery.prototype으로 지정하세요.
이 작업이 완료되었습니다. init를 사용하여 인스턴스화하면 init 범위에서 jQuery.prototype에 액세스할 수 있습니다.
function jQuery(sel){ return new jQuery.prototype.init(sel); } jQuery.prototype = { constructor: jQuery, init: function(sel){ if(typeof sel === 'string'){ var that = this; //jQuery内部使用的是Sizzle,这里使用querySelectorAll替代 var nodeList = document.querySelectorAll(sel); Array.prototype.forEach.call(nodeList, function(val, i){ that[i] = val; }) this.selector = sel; this.length = nodeList.length; } } } jQuery.prototype.init.prototype = jQuery.prototype;
jQuery 함수를 직접 사용하는 대신 jQuery.prototype.init를 사용하여 객체를 인스턴스화하는 이유는 무엇입니까?
jQuery 함수가 객체를 인스턴스화하는 데 사용되어 객체 간의 참조가 실제로 jQuery-->jQuery.prototype으로 단순화될 수 있다고 가정합니다.
그러나 호출이 번거로워질 것입니다. new $('div')이므로 이러한 고려 사항을 기반으로(추측(⊙0⊙)) 호출을 단순화하기 위해 내부적으로 더 복잡한 구현이 사용됩니다.
---------------
자, 마지막으로 init 구현을 살펴보겠습니다. 코드도 단순화되어 가장 일반적으로 사용되는 경우만 구현됩니다.
jQuery는 획득한 nodeList를 배열로 처리하고(이후 사용의 편의를 위해) 그 아래에 길이 및 선택기와 같은 일부 변수를 마운트합니다.
init: function(sel){ if(typeof sel === 'string'){ var that = this; //jQuery内部使用的是Sizzle,这里使用querySelectorAll替代 var nodeList = document.querySelectorAll(sel); Array.prototype.forEach.call(nodeList, function(val, i){ that[i] = val; }) this.selector = sel; this.length = nodeList.length; } }
이번 글은 여기서 마치겠습니다. 다음 글에서는 jQuery 체인콜에 대한 간략한 분석과 지식을 보여드리겠습니다. 자세한 내용은 스크립트하우스 홈페이지를 참고해주세요!