jQuery.fn与jQuery.prototype的关系解析

作者:资源驿站时间:2026-10-28 04:19:45浏览:495

本文深入解析jQuery源码中jQuery.fn与jQuery.prototype的关系。通过分析源码可知,jQuery将jQuery.fn直接赋值给jQuery.prototype,同时又将init函数的原型指向jQuery.fn。这种设计使得通过jQuery.fn扩展的方法能作用于所有jQuery实例,而jQuery.extend扩展静态方法。理解这一机制有助于掌握jQuery扩展插件及API设计的核心原理。

jQuery核心变量解析

在近期研读jQuery源码的过程中,



注意到其中涉及的一个概念容易让人产生困惑。



具体而言,jQuery、jQuery.fn、init以及jQuery.prototype各自代表什么含义?



我们可以从jQuery的源码定义中找到答案:


核心代码结构如下:

 
(function( window, undefined ) {
var jQuery = (function() {
// 构建jQuery对象
var jQuery = function( selector, context ) {
return new jQuery.fn.init( selector, context, rootjQuery );
} 
// jQuery对象原型
jQuery.fn = jQuery.prototype = {
constructor: jQuery,
init: function( selector, context, rootjQuery ) {
// something to do
} 
}; 
// Give the init function the jQuery prototype for later instantiation
jQuery.fn.init.prototype = jQuery.fn;
// 合并内容到第一个参数中,后续大部分功能都通过该函数扩展
// 通过jQuery.fn.extend扩展的函数,大部分都会调用通过jQuery.extend扩展的同名函数
jQuery.extend = jQuery.fn.extend = function() {};
// 在jQuery上扩展静态方法
jQuery.extend({
// something to do
}); 
// 到这里,jQuery对象构造完成,后边的代码都是对jQuery或jQuery对象的扩展
return jQuery;
})(); 
window.jQuery = window.$ = jQuery;
})(window);

原型链与扩展机制

通过上述代码可以观察到:


关键赋值逻辑如下:

 
var jQuery = function( selector, context ) {
return new jQuery.fn.init( selector, context, rootjQuery );
} 

可以看出,jQuery()构造函数实际上返回的是jQuery.fn.init()创建的一个对象。那么,jQuery.fn.init()具体返回的是什么类型的对象呢?


相关定义代码如下:

 
jQuery.fn = jQuery.prototype = {
constructor: jQuery,
init: function( selector, context, rootjQuery ) {
// something to do
} 
}; 

答案就在这里,它返回的是一个JavaScript对象。



这里存在一个关键问题。


代码片段如下:

 
jQuery.fn = jQuery.prototype

这意味着将jQuery的原型对象直接赋值给了jQuery.fn。



接着看下面的代码:


代码片段如下:

 
jQuery.fn.init.prototype = jQuery.fn;

由此可以推断,jQuery.fn被赋值给了jQuery.fn.init.prototype。



那么在赋值之前,jQuery.fn.init.prototype是什么?



此时它的原型默认为空对象{}。



为了让init实例能够调用外部的方法,代码进行了特殊处理。



将jQuery.fn赋值给jQuery.fn.init.prototype后,



jQuery.fn.init.prototype的原型即jQuery的原型对象,也就是jQuery.fn(注意jQuery = function(return new jQuery.fn.init()))。



赋值完成后,当调用init中不存在的方法时,就会沿着原型链去jQuery.fn中查找并调用。



这样一来,



你可能会注意到这样的区别:


代码对比如下:

 
jQuery.extends()
jQuery.fn.extends()

相信你已经明白它们的区别所在。



jQuery.extend()是直接扩展jQuery构造函数本身,而jQuery.fn.extend()则是扩展原型对象。



这就是为什么jQuery.fn.extend()中的大部分方法实际上来源于jQuery.extend()的原因。



这里再次将jQuery.fn赋值给了jQuery.fn.init.prototype。



因此形成了如下关系:


关键等式如下:

 
jQuery.prototype = jQuery.fn = jQuery.fn.init.prototype
作者最新文章