jQuery:源码与扩展

源码与扩展

源码

jQuery有很多设计是⾮常优秀的

The Write Less,Do More(写更少,做更多),⽆疑是JQuery的核⼼理念,简洁的API、优雅的链式、强⼤查询与便捷的操作。

经典细节1_⽴即执⾏函数

(function(global, factory){
 ...
})(typeof window !== "undefined" ? window : this, function( window,
noGlobal(){...});

Q:采⽤⽴即执⾏函数,这样做,有什么好处呢?
A:通过定义⼀个匿名函数,创建了⼀个新的函数作⽤域,相当于创建了⼀个“私有”的命名空间,该命名空间的变量和⽅法,不会破坏污染全局的命名空间。此时若是想访问全局对象,将全局对象以参数形式传进去即可。此外,新作⽤域内对象想访问传⼊的全局对象时,就不需要⼀步⼀步的往上找,可提⾼效率。

经典细节2_链式调⽤

$("div,parent").nextAll().first();

如何做到链式调⽤呢

var test = {
  a:function(){
	 console.log('a');
	 return this;
  },
  b:function(){
	 console.log('b');
	 return this;
  },
  c:function(){
 	console.log('c');
  }
}
test.a().b().c();

经典细节3_闭包下的重载

$('.test','td')
$(['.test','#id'])
$(function(){...})

$()就是⼀个函数,参数不同,就涉及到了函数的重载。参数个数不等,⽤传统js实现起来⾮常困难。那么jQuery究竟是如何实现的呢?

看⽤下⾯代码的实现

function addMethod( object, name, func ) {
 	var old = object[name];
 	object[name] = function(){
		 if(func.length === arguments.length){
 			return func.apply(this,arguments);
 		}else{
 			return old.apply(this,arguments);
 		}
 	}
}
var people = {
 	name:["a","b","c"]
}
var find0 = function(){
 	return this.name;
}
//新增
var find1 = function(name){
 	var arr = this.name;
 	for(var i = 0;i <= arr.length;i++ ){
 		if(arr[i]=name){
 			return arr[i];
 		}
 	}
}
addMethod(people,'find',find0);
//新增
addMethod(people,'find',find1);
console.log(people.find());//["a", "b", "c"]
console.log(people.find("a"));//a

经典细节4_init()

我们看如下截图
在这里插入图片描述
令⼈惊讶的是,new出来的和直接调⽤的,居然是⼀模⼀样的。
这是为什么呢? 这就涉及到了jQuery的经典的init操作:
在这里插入图片描述
从上⾯这张图,我们可以了解到:

  1. 第⼀个红框:调⽤ jQuery ,返回的是new jQuery.fn.init(selector,context);init⽅法被挂在到了jQuery.fn上的。
  2. 第⼆个红框:jQuery.fn = jQuery.prototype = {...};

为了⽅便讲解,我们对其进⾏⼀些简化:

//1
jQuery = function( selector, context ) {
  return new jQuery.fn.init( selector, context );
}
//2
jQuery.fn = jQuery.prototype = {
	init:function( selector, context ){
 ...
 }
}
//3
init = jQuery.fn.init = function( selector, context, root ){
 ...
}
init.prototype = jQuery.fn;

步骤1:我们从代码块2开始看,jQuery.prototype = jQuery.fn,且都挂载了init()函数。
步骤2:再看代码块3,jQuery.fn.init.prototype = jQuery.fn,⽽我们从步骤1中,了解到jQuery.prototype = jQuery.fn。因此 jQuery.fn.init.prototype = jQuery.fn = jQuery.prototype
步骤3:最后,再回过来看代码块1,function返回的是new jQuery.fn.init(..)。我们再看步骤2,
jQuery.fn.init.prototype = jQuery.prototype。那么,new jQuery.fn.init(..)就相当于function返回了⼀个new jQuery()。

饶了⼀⼤圈,就相当于 jQuery = new JQuery();
Q:那么,为啥要绕那么远呢?
A:为了得到jQuery原型链上的⽅法。

扩展

接下来我们扩展jQuery⽅法

  1. 扩展⼀个print()⽅法,获得当前元素的内容
$.fn.extend({
 	print:function(){
 		console.log($(this).html())
 	}
 })
$("p").print();
  1. 我们也可以传递参数
(function($){
 	$.fn.print=function(options){
 		$(this).html(options)
 }
})(jQuery);
$("p").print("demo")

BootStrap框架模块:BootStrap4基础

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值