jQuery.fn.init 返回的 this

理解 jQuery 构造函数中 this 的指向

问题

jQuery.fninit 方法返回的 this 指的是什么对象?

解答

jQuery.fn.init 返回的 this 指向 jQuery 实例对象(也叫 jQuery 包装对象)。

jQuery 源码结构

// jQuery 构造函数
var jQuery = function(selector, context) {
    // 返回 init 的实例
    return new jQuery.fn.init(selector, context);
};

// jQuery.fn 是 jQuery.prototype 的别名
jQuery.fn = jQuery.prototype = {
    constructor: jQuery,
    
    // init 是真正的构造函数
    init: function(selector, context) {
        // 处理各种选择器情况
        if (!selector) {
            return this; // 返回空 jQuery 对象
        }
        
        if (typeof selector === 'string') {
            // 查找 DOM 元素,添加到 this 上
            var elems = document.querySelectorAll(selector);
            for (var i = 0; i < elems.length; i++) {
                this[i] = elems[i];
            }
            this.length = elems.length;
        }
        
        // 返回 jQuery 实例
        return this;
    },
    
    length: 0
};

// 关键:让 init 的原型指向 jQuery.fn
// 这样 init 的实例就能访问 jQuery.fn 上的所有方法
jQuery.fn.init.prototype = jQuery.fn;

简化示例

// 模拟 jQuery 结构
function MyQuery(selector) {
    return new MyQuery.fn.init(selector);
}

MyQuery.fn = MyQuery.prototype = {
    init: function(selector) {
        var elems = document.querySelectorAll(selector);
        for (var i = 0; i < elems.length; i++) {
            this[i] = elems[i];
        }
        this.length = elems.length;
        
        // this 是 init 的实例
        // 由于 init.prototype = MyQuery.fn
        // 所以 this 可以访问 MyQuery.fn 上的方法
        return this;
    },
    
    length: 0,
    
    css: function(prop, value) {
        for (var i = 0; i < this.length; i++) {
            this[i].style[prop] = value;
        }
        return this; // 链式调用
    }
};

MyQuery.fn.init.prototype = MyQuery.fn;

// 使用
var $divs = MyQuery('div');
console.log($divs);        // init {0: div, 1: div, length: 2}
console.log($divs[0]);     // 原生 DOM 元素
$divs.css('color', 'red'); // 调用 jQuery 方法

this 的结构

// $('div') 返回的 this 结构类似:
{
    0: div元素1,
    1: div元素2,
    2: div元素3,
    length: 3,
    __proto__: jQuery.fn  // 可以访问所有 jQuery 方法
}

关键点

  • jQuery.fnjQuery.prototype 的别名
  • init 是 jQuery 真正的构造函数,jQuery() 内部调用 new jQuery.fn.init()
  • this 是一个类数组对象,包含匹配的 DOM 元素和 length 属性
  • jQuery.fn.init.prototype = jQuery.fn 让 init 实例能访问所有 jQuery 方法
  • 返回 this 实现链式调用