jquery源码学习笔记之$.fn.extend与$.extend调用差异

183 阅读1分钟

源码版本 jquery-3.4.1.js, 以如下方法举例:

$.fn.extend({
    alertaaa: function () {
        console.log('aaa')
    }
})
$.extend({
    alertbbb: function () {
        console.log('bbb')
    }
})
$('#id1').alertaaa() // console.log('aaa')
$.alertbbb() // console.log('bbb')

$ = jQuery,jQuery本身是个静态方法,jQuery函数里返回的是一个jquery.fn.init的实例。

jQuery = function( selector, context ) {
	// The jQuery object is actually just the init constructor 'enhanced'
	// Need init if jQuery is called (just allow error to be thrown if not included)
	return new jQuery.fn.init( selector, context );
},

源码中有关jquery.fn的代码如下:

jQuery.fn = jQuery.prototype

init.prototype = jQuery.fn;

init.prototype就等于jQuery.prototype,说明init.prototype能够使用jQuery.prototype里的方法,那么根据js原型链可得init方法的实例可以使用jQuery.prototype里的方法

jQuery.extend, jQuery.fn.extend这两个方法都是给jquery扩展属性,不同的是前者是给jQuery扩展,后者是给jQquery.prototype扩展的,那么例子中的jQuery扩展之后,jQuery.prototype便多了alertaaa方法,jQuery静态方法多了alertbbb方法

)

// jQuery返回的init的实例通过原型链,在jQuery原型上找到了alertaaa方法,从而console.log('aaa')
$('#id1').alertaaa() => jQuery('#id1').alertaaa() => new jQuery.fn.init('#id1').alertaaa() 
// 直接去jQuery静态方法里去找alertbbb方法,从而console.log('bbb')
$.alertbbb() => jQuery.alertbbb()

同样的道理,例如

$('#id1').text()

源码中text方法是在jQuery.fn.extend里扩展的,也就是说在jQuery的原型里有text方法

jQuery.fn.extend( {
	text: function( value ) {
	    
	}
})

// jQuery返回的init的实例通过原型链,在jQuery原型上找到了text方法,然后进行调用
$('#id1').text() => jQuery('#id1').text() => new jQuery.fn.init('#id1').text()