# JQuery源码解析 **Repository Path**: The_order/jquery-source-code-analysis ## Basic Information - **Project Name**: JQuery源码解析 - **Description**: JQuery源码解析 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2025-05-14 - **Last Updated**: 2025-05-14 ## Categories & Tags **Categories**: Uncategorized **Tags**: JavaScript, jQuery ## README ## 模拟jQuery实现 下面我们通过模拟实现一个简单的`jQuery`,来巩固原型的应用。 ```js ``` 下面,我们使用`jQuery`原型中的`size`方法和`version`属性。 ```js // 为jQuery起一个别名,模仿jQuery的框架 var $ = (jQuery = function () {}); // 为jQuery原型起一个别名 //这里没有直接赋值给fn,否则它属于window对象,容易造成全局污染 //后面要访问jquery的原型,可以直接通过jQuery.fn来实现 jQuery.fn = jQuery.prototype = { version: "6.1.1", //添加原型属性,表示jquery的版本 //添加原型方法,表示返回jquery对象的长度 size: function () { return this.length; }, }; var jq = new $(); console.log(jq.version); // 6.1.1 console.log(jq.size()); // undefined ``` 在上面的代码中,我们是创建了一个`jquery`的实例,然后通过该实例完成了原型属性和方法的调用。 但是在`jquery`库中,是采用如下的方式进行调用。 ```js $().version; $().size() ``` 通过以上的两行代码,我们可以看到在`jQuery`库中,并没有使用`new`操作符,而是直接使用小括号运算符完成了对`jQuery`构造函数的调用。然后后面直接访问原型成员。 那应该怎样实现这种操作? 我们想到的就是,在`jquery`的构造函数中,直接创建`jQuery`类的实例。 ```js // 为jQuery起一个别名,模仿jQuery的框架 var $ = (jQuery = function () { return new jQuery(); }); // 为jQuery原型起一个别名 //这里没有直接赋值给fn,否则它属于window对象,容易造成全局污染 //后面要访问jquery的原型,可以直接通过jQuery.fn来实现 jQuery.fn = jQuery.prototype = { version: "6.1.1", //添加原型属性,表示jquery的版本 //添加原型方法,表示返回jquery对象的长度 size: function () { return this.length; }, }; $().version; // var jq = new $(); // console.log(jq.version); // 6.1.1 // console.log(jq.size()); ``` 在上面的代码中,给`jQuery`构造函数直接返回了`它的实例`,`return new jQuery();` 然后获取原型对象中的`size`属性的值:`$().version`. 但是,出现了如下的错误: ``` Uncaught RangeError: Maximum call stack size exceeded ``` 以上错误的含义是栈内存溢出。 原因就是:当我们通过`$()`调用构造函数的时候,内部有执行了`new`操作,这时,又会重新执行`jQuery`的构造函数,这样就造成了死循环。 ```js var $ = (jQuery = function () { return jQuery.fn.init(); //调用原型中的`init方法` }); jQuery.fn = jQuery.prototype = { init: function () { return this; //返回jquery的原型对象 }, version: "6.1.1", size: function () { return this.length; }, }; console.log($().version); ``` 在上面的代码中,在`jQuery`的构造方法中,调用的是原型中的`init`方法,在该方法中,返回了`jquery`的原型对象。 最后进行输出:`cosnole.log($().version)` 但是,以上的处理还是隐藏一个问题,具体看如下代码: ```js var $ = (jQuery = function () { return jQuery.fn.init(); }); jQuery.fn = jQuery.prototype = { init: function () { this.length = 0; //原型属性length this._size = function () { //原型方法 return this.length; }; return this; }, version: "6.1.1", length: 1, // 原型属性 size: function () { return this.length; }, }; console.log($().version); console.log($()._size()); // 0 console.log($().size()); // 0 ``` 在上面的代码中,在`init`这个原型方法中添加了`lenght`属性与`_size`方法,在该方法中打印`length`的值。 ```js var $ = (jQuery = function () { return new jQuery.fn.init(); //调用原型中的`init方法` }); ``` 在`jQuery`的构造函数中,通过`new`操作符创建了一个实例对象,这样`init()`方法中的`this`指向的就是`init`方法的实例,而不是`jQuery.prototype`这个原型对象了。 ```js console.log($().version); // 返回undefined console.log($()._size()); // 0 console.log($().size()); // 抛出异常:Uncaught TypeError: $(...).size is not a function ``` 下面,我们来看一下怎样解决现在面临的问题。 ```js var $ = (jQuery = function () { return new jQuery.fn.init(); //调用原型中的`init方法` }); jQuery.fn = jQuery.prototype = { init: function () { this.length = 0; this._size = function () { return this.length; }; return this; }, version: "6.1.1", length: 1, size: function () { return this.length; }, }; // 将`jQuery`的原型对象覆盖掉init的原型对象。 jQuery.fn.init.prototype = jQuery.fn; console.log($().version); //6.1.1 console.log($()._size()); // 0 console.log($().size()); // 0 ``` 在上面的代码中,我们添加了一行代码: ```js jQuery.fn.init.prototype = jQuery.fn; ``` ```js console.log($().version); ``` **下面,要实现的是选择器功能** `jQuery`构造函数包括两个参数,分别是`selector`和`context`,`selector`表示的是选择器,`context`表示匹配的上下文,也就是可选择的访问,一般表示的是一个`DOM`元素。这里我们只考虑标签选择器。 ```js
``` 在上面的代码中,当页面加载完以后,这时会触发`onload`事件,在该事件对应的处理函数中,通过`$("div")`,传递的是字符串, `selector`参数表示的就是`div`这个字符串,这里没有传递`context`参数,表示的就是`document`对象。 最后打印元素的个数。 在使用`jQuery`库的时候,我们经常可以看到如下的操作: ```js $('div').html() ``` 以上代码的含义就是直接在`jQuery`对象上调用`html( )`方法来操作`jQuery`包含所有的`DOM`元素。 `html()`方法的实现如下: ```js