제2장 jQuery 기술 복호화(一)
모든 복잡한 기술은 가장 간단한 문제에서 시작된다. 만약에 당신이 jQuery 수천 줄의 복잡한 구조의 원본 코드에 곤혹스러우면 이 절의 내용을 읽는 것을 권장한다. 우리는 jQuery가 어떻게 가장 간단한 문제에서 시작하고 점차적으로 날개가 돋보이는 변화 과정을 실현하는지 탐색할 것이다.jQuery 핵심 기술의 복원 과정에서 jQuery 프레임워크의 구축 원리를 이해한다.
2.2.1 기원-원형 계승
JavaScript를 사용한 독자들은 JavaScript 스크립트에 함수가 곳곳에 있고 함수는 코드 세그먼트를 귀착시켜 상대적으로 독립된 기능을 함수 패키지에 봉인할 수 있다는 것을 알게 될 것이다.함수도 클래스를 실현할 수 있다. 이 클래스는 대상을 대상으로 프로그래밍하는 가장 기본적인 개념이자 가장 추상적이다. 하나의 클래스를 정의하는 것은 하나의 모델을 만든 것과 같다. 그리고 이 모델을 빌려 무수한 실례를 복제한다.
예를 들어 다음 코드는 최초의 jQuery 클래스를 정의할 수 있습니다. 클래스 이름은 jQuery입니다. 함수를 함수로 볼 수 있습니다. 함수 이름은 jQuery입니다.물론, 너도 그것을 하나의 대상으로 볼 수 있다. 대상 이름은 jQuery이다.다른 대상을 대상으로 하는 프로그래밍 언어에 비해 자바스크립트는 이 개념에 대한 정의가 자유로운 것 같아서 프로그래밍의 문턱을 낮추고 반대로 자바스크립트가 프로그래밍 언어로서의 차원을 낮춘다.
var jQuery = function(){
//함수체
};
위에 빈 함수를 만들었습니다. 아무것도 할 수 없을 것 같습니다. 이 함수는 사실상 이른바 구조 함수입니다.구조 함수는 대상 언어에서 클래스를 만드는 특수한 방법으로 클래스를 만드는 데 사용된다.JavaScript에서, 당신은 모든 함수를 구조 함수로 볼 수 있습니다. 이것은 안 될 것이 없습니다. 이렇게 하면 코드 자체를 해치지 않습니다.
모든 종류는 계승, 파생, 재작성 등 가장 기본적인 기능을 가지고 있다.JavaScript는 특이하게도 모든 함수에prototype 속성을 연결합니다. 이 속성은 원형 대상을 가리키며, 원형 대상에서 클래스의 계승 속성과 방법 등을 정의할 수 있습니다.따라서 위의 빈 클래스에 대해 원형을 계속 확장할 수 있으며 코드는 다음과 같다.
var jQuery = function(){};
jQuery.prototype = {
//확장된 원형 대상
};
원형 대상은 자바스크립트가 계승을 실현하는 기본 메커니즘이다.
만약 당신이 jQuery라고 생각한다면.prototype의 이름이 너무 길어서 상관없습니다. fn과 같이 이름을 바꿀 수 있습니다. 물론 마음대로 이름을 지을 수 있습니다.fn을 직접 명명하면, 이 이름 속성 윈도 대상, 즉 전역 변수 이름을 표시합니다.더 안전한 방법은 jQuery 클래스에 공공 속성을 정의하는 것입니다. jQuery.fn, 그리고 jQuery의 원형 대상을 이 공공 속성 에 전달하고 코드는 다음과 같습니다.
jQuery.fn = jQuery.prototype = {
//확장된 원형 대상
};
여기 jQuery.fn은 jQuery에 해당합니다.prototype의 별명으로 나중에 사용하기 편리합니다. 같은 인용을 가리킵니다.
따라서 jQuery의 원형 방법을 호출하려면 jQuery를 직접 사용하십시오.fn 공통 속성은 jQuery를 직접 참조할 필요가 없습니다.prototype, 물론 jQuery를 직접 사용합니다.prototype도 가능합니다.
원형 대상이 별명을 사용할 수 있는 이상, jQuery 클래스도 별명을 만들 수 있습니다. $기호로 을 인용할 수 있습니다. 코드는 다음과 같습니다.
var $ = jQuery = function(){};
현재 jQuery 프레임워크 원본을 모방하여 두 명의 구성원을 추가합니다. 하나는 원형 속성 jquery, 하나는 원형 방법 size () , 코드는 다음과 같습니다.
var $ = jQuery = function(){};
jQuery.fn = jQuery.prototype = {
jquery: "1.3.2",//원형 속성
size:function() {//원형 방법
return this.length;
}
};
2.2.2 생명 - 실례로 돌아가기
우리가 jQuery에 두 개의 원형 구성원을 추가한 후에 jquery 속성과size () 방법을 추가한 후에 이 프레임워크의 가장 기본적인 모습이 탄생했다.그러나 jquery 속성과size () 방법을 어떻게 호출해야 합니까?p>
혹시 당신은 다음과 같은 방법으로 호출할 수 있습니다:
var my$ = new $(); //실례화
alert(my$.jquery);//호출 속성,'1.3.2'반환
alert(my$.size());//호출 방법,undefined
되돌아오기하지만 jQuery는 이렇게 호출되지 않습니다.그것은 아래와 유사한 방법을 모방하여 호출한다.
$().jquery;
$().size();
즉, jQuery는 new 연산자를 사용하여 jQuery 클래스를 실례화하지 않고, jQuery () 함수를 직접 호출한 다음, 이 함수 뒤에서 jQuery의 원형 방법을 직접 호출합니다. 이것은 어떻게 실현된 것입니까?
jQuery 프레임워크의 사용법을 모방하여 다음 코드를 실행하면 브라우저에 컴파일 오류가 표시됩니다.이것은 위의 사례 코드가 아직 진정한 jQuery 기술의 원형이 아니라는 것을 설명한다.
alert($().jquery);
alert($().size());
즉, 우리는 jQuery를 하나의 클래스로 간주해야 하며, 동시에 그것을 하나의 일반 함수로 간주해야 하며, 이 함수의 반환 값을 jQuery 클래스의 실례로 간주해야 한다. 그러므로 아래의 이런 구조 모델이 정확하다.
var $ = jQuery = function(){
return new jQuery(); // 返回类的实例
};
jQuery.fn = jQuery.prototype = {
jquery: "1.3.2", // 原型属性
size: function(){ // 原型方法
return this.length;
}
};
alert($().jquery);
alert($().size());
但是,如果在浏览器中预览,则会提示如图 2.1 所示的错误。内存外溢,说明出现了死循环引用。
那么如何返回一个 jQuery 实例呢?
回忆一下,当使用 var my$ = new $(); 创建 jQuery 类的实例时,this 关键字就指向对象 my$ ,因此 my$ 实例对象就获得了 jQuery.prototype 包含的原型属性或方法,这些方法内的 this 关键字就会自动指向 my$ 实例对象。换句话说,this 关键字总是指向类的实例。
因此,我们可以这样尝试:在 jQuery 中使用一个工厂方法来创建一个实例 (就是 jQuery.fn),把这个方法放在 jQuery.prototype 原型对象中,然后在 jQuery() 函数中返回这个原型方法的调用。代码如下所示。
var $ = jQuery = function(){
return jQuery.fn.init(); // init()
};
jQuery.fn = jQuery.prototype = {
init: function(){ //
return this;
},
jquery: "1.3.2", //
size: function(){ //
return this.length;
}
};
alert($().jquery); // , "1.3.2"
alert($().size()); // , undefined
2.2.3 걸음마-역할 영역 구분
우리는 jQuery () 함수가 jQuery 클래스의 실례를 되돌릴 수 있도록 초보적으로 실현했다. 다음에 계속 생각해 보자. init () 방법은this 키워드를 되돌려준다. 이 키워드는 jQuery 클래스의 실례를 인용한다. 만약에 init () 함수에서this 키워드를 계속 사용한다면 init () 함수도 하나의 구조기로 간주하고그중의this는 어떻게 이해하고 처리해야 합니까?
예를 들어 다음 예시에서 jQuery 원형 대상에는length 속성이 포함되어 있고 init()는 일반적인 함수에서 구조기로 바뀌며,length 속성과test() 방법도 포함되어 있습니다.이 예시를 실행하면 this 키워드는 init () 함수 작용역이 있는 대상을 인용하고, 이때length 속성에 접근할 때 0을 되돌려줍니다.this 키워드도 상위 대상 jQuery에 접근할 수 있습니다.fn 대상의 역할 영역입니다. 따라서 $().jquery 반환 & #34;1.3.2" .하지만 $()를 호출합니다.크기 () 방법에서 1이 아닌 0을 되돌려줍니다.
4
var $ = jQuery = function(){
return jQuery.fn.init(); // init()
};
jQuery.fn = jQuery.prototype = {
init: function(){ //
this.length = 0;
this.test = function(){
return this.length;
}
return this;
},
jquery: "1.3.2", //
length: 1,
size: function(){ //
return this.length;
}
};
alert($().jquery); // "1.3.2"
alert($().test()); // 0
alert($().size()); // 0
이런 디자인 사고방식은 작용역의 독립성을 파괴하기 쉽고 jQuery와 같은 구조에 부정적인 영향을 미칠 수 있다.따라서, jQuery 프레임워크는 다음 방식으로 init () 를 호출하여 구조 함수를 초기화하는 것을 볼 수 있습니다.
var $ = jQuery = function(){
return new jQuery.fn.init();//실례화 init 초기화 형식, 구분 작용역
};
이렇게 하면 init () 구조기의 this와 jQuery를 사용할 수 있습니다.fn 대상 중의this 키워드를 분리하여 서로 혼동을 피합니다.그러나 이런 방식도 또 다른 문제를 가져올 수 있다. jQuery에 접근할 수 없다.fn 대상의 속성이나 방법입니다.예를 들어, 다음 예에서 jQuery에 액세스합니다.fn 원형 대상의 jquery 속성과size () 방법이 있을 때 이 문제가 발생합니다.
var $ = jQuery = function(){
return new jQuery.fn.init(); // 实例化 init 初始化类型,分隔作用域
};
jQuery.fn = jQuery.prototype = {
init: function(){ // 在初始化原型方法中返回实例的引用
this.length = 0;
this.test = function(){
return this.length;
}
return this;
},
jquery: "1.3.2", // 原型属性
length: 1,
size: function(){ // 原型方法
return this.length;
}
};
alert($().jquery); // 返回 undefined
alert($().test()); // 返回 0
alert($().size()); // 抛出异常
2.2.4 生长 -- 跨域访问
如何做到既能够分隔初始化构造器函数与 jQuery 原型对象的作用域,又能够在返回实例中访问 jQuery 原型对象呢?
jQuery 框架巧妙地通过原型传递解决了这个问题,它把 jQuery.fn 传递给 jQuery.fn.init.prototype ,也就是说用 jQuery 的原型对象覆盖 init 构造器的原型对象,从而实现跨域访问,其代码如下所示。
var $ = jQuery = function(){
return new jQuery.fn.init(); // init ,
};
jQuery.fn = jQuery.prototype = {
init: function(){ //
this.length = 0;
this.test = function(){
return this.length;
}
return this;
},
jquery: "1.3.2", //
length: 1,
size: function(){ //
return this.length;
}
};
jQuery.fn.init.prototype = jQuery.fn; // jQuery init
alert($().jquery); // "1.3.2"
alert($().test()); // 0
alert($().size()); // 0
이것은 묘기입니다.
2.2.5 성숙-선택기
jQuery는 jQuery 대상을 되돌려줍니다. jQuery 대상은 하나의 클래스 그룹의 대상입니다. 본질적으로 이것은 대상 이지만, 그룹의 길이와 하표를 가지고 있지만, 그룹을 계승하는 방법이 없습니다.
위의 몇 절의 설명은 모두 공이론을 바탕으로 한 것으로 독자가 jQuery 프레임워크의 핵심 구축 과정을 이해하기를 바란다.다음은 jQuery () 함수에 매개 변수를 전달하고 jQuery 대상을 되돌려 줍니다.
jQuery () 함수는 두 개의 매개 변수인 selector와 context를 포함하는데, 그 중에서 selector는 선택기를 표시하고, context는 선택한 내용의 범위를 표시하며,DOM 요소를 표시합니다. 조작을 간소화하기 위해 선택기의 종류는 탭 선택기로 한정된다고 가정합니다.구현된 코드는 다음과 같습니다.
var $ = jQuery = function(selector, context){ //
return new jQuery.fn.init(selector, context); //
};
jQuery.fn = jQuery.prototype = { // jQuery
init: function(selector, context){ //
selector = selector || document; // document
context = context || document; // document
if(selector.nodeType){ //
this[0] = selector; //
this.length = 1; // length ,
this.context = selector; // ,
return this; //
}
if(typeof selector === "string"){ //
var e = context.getElementsByTagName(selector); //
for(var i = 0; i<e.length; i++){ // ,
this[i] = e[i];
}
this.length = e.length; // length ,
this.context = context; // ,
return this; //
} else {
this.length = 0; // , length 0
this.context = context; // ,
return this; //
}
},
jquery: "1.3.2", //
size: function(){ //
return this.length;
}
};
jQuery.fn.init.prototype = jQuery.fn; // jQuery init
alert($("div").size()); // 3
위 예시에서 $("div")기본적으로 jQuery 프레임워크에 $(& #34; div & #34;) 가 있습니다.페이지에서 지정된 범위의 div 요소를 선택할 수 있는 구문 기능입니다.또한 크기 () 방법을 호출하면 jQuery 대상 집합의 길이를 되돌려줍니다.