关于创建jQuery以及jQuery.fn.init.prototype = jQuery.fn的作用

荆钱明
2023-12-01

本文以jQuery 2.0.3分析为例

关于构造函数的两个点

  • 在JS中创建对象必须要使用new,否则就如同构建了一个普通对象,this表示未来创建的实例, 并返回this
function Student (school) {
  this.school = school
}

new Student('hdu') // 创建了对象 {school: 'hdu'}
Student('hdu') // 仅仅是执行了一个函数 并无其他作用
  • 如果构造函数中有返回值return xxx 如果xxx是个复杂类型(对象,数组…)时,最终返回这个复杂类型(对象,数组…)
function Student (school) {
  this.school = school
  return 666
}
new Student('hdu') // {school: 'hdu'}

function Student (school) {
  this.school = school
  return {name: 'LiHua'}
}
new Student('hdu') // {name: 'LiHua'}

jQuery.fn.init.prototype = jQuery.fn的作用

首先在jQuery中定义了 jQuery.fn = jQuery.prototype ,其应该是方便后续的调用,fn就是prototype

我们在调用jQuery的时候,是采用$('')($ = jQuery)

我们都知道jQuery是面向对象的思想,其$('').css(),那么我们就能推测出来,$('')返回值是一个对象,
但是之前我们看到构造函数必须要使用new这个关键字才行,也就是new $('')
然而jQuery目的就是让我们write less,所以我们自然就推测出来,$('')他的返回值是一个对象

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

这也就证明了我们的推测, 调用$('')其返回值是jQuery.fn.init的一个实例

那么问题又来了,我们在使用的时候,好多方法都是挂载到$原型上面的,那么既然创建出的是jQuery.fn.init的一个实例,
调用$('').css() 那么这个css()应该在jQuery.fn.init的原型上才对,但是纵观源码,都是对jQuery的原型操作的,
我们自己定义拓展方法也是 $.fn.myFunction,这都说明了我们确实是挂载到 $的原型上的,所以我们不妨大胆假设一下,
jQuery.fn.init的原型就是jQuery的原型,这样才能很好的解释我们的推测,也就说明了我们虽然创建出的是jQuery.fn.init的一个实例,
由于其原型也是jQuery的原型,所以我们给jQuery添加的拓展方法,自然就关联到jQuery.fn.init上了

带着问题向下翻,果不其然!

// Give the init function the jQuery prototype for later instantiation
jQuery.fn.init.prototype = jQuery.fn;

总结

jQuery为了我们书写方便,避免了new $(' '), 但是他的源码中帮我们new了一个对象出来,为了关联,就只能把jQuery的原型和底层帮我们new出来的这个的原型绑定在一起,

这就有一个假象: $(''),给我们 new 了一个jQuery出来。

  • 其实我们用的是jQuery.fn.init的实例
  • jQuery也只是一个方法名
 类似资料: