最近在看jQuery框架的源码,感觉还是学到不少东西的,所以就想总结一下自己的知识,和广大的前端爱好者一起
交流一下,我下面所说的并不是直接对jQuery的源码来解读,我是模拟一下jQuery底层源码的链式调用大概是怎么
实现的和常用的$功能是怎么实现的。好了废话不多说了。
你要看这个,你就要对jQuery有一定的了解,最起码你要用过jQuery。
首先看下jQuery的源码开始是怎么写的
(function( window, undefined){
})(window);
它的代码就是被这个块级作用域包裹着,
这里我有必要说一下块级作用域
(function(){
//这就是一个最简单的块级作用域
//特点1:程序启动的时候,里面的代码就直接执行了
alert(‘我执行了‘); //我执行了
//特点2:内部的成员变量,外部是无法访问,(除了不加var的变量)
var a =10;
})();
alert(a); //a is not defined
上面,我们了解了块级作用域的概念了,也就明白了
里面的成员和方法是不可以被外界所调用的,
但是jQuery不是一开始就可以用$这个功能吗
(function( window, undefined){
//里面的代码,就要把$返回给外界
})(window); //window相当于程序的入口,把参数window传入作用域中
好了,我们下面就开始说下jQuery了
(function(window,undefined){
//在大型程序开发中,一般使用‘_‘作为私有的对象
function _$(arguments){
};
//window上先注册一个全局变量,与外界产生关系
window.$ = _$;
//写一个准备的方法
_$.onReady = function(fn){
fn(); //11
};
})(window);
//jQuery的调用一般这样写
$.onReady(function(){
alert(11);
});
//这样就实现了$.onReady这个方法了
但是这样还不是很合理,我们还要完善一下
(function(window,undefined){
//在大型程序开发中,一般使用‘_‘作为私有的对象
function _$(arguments){
};
//_$这是个类,也是一个函数,所以 也属于Function
Function.prototype.method = function(methodName,fn){
this.prototype[methodName] = fn;
//实现链式编程的关键
return this;
};
//在_$的原型对象中加一些公共的方法
_$.prototype ={
//还原构造器
constructor:_$,
//添加事件方法
addEvent:function(){
alert(‘addEvent‘);
//这里才是我们真正实现具体方法的链式编程
return this;
},
//改变样式
setStyle:function(){
alert(‘setStyle‘);
//这里才是我们真正实现具体方法的链式编程
return this;
}
};
//window上先注册一个全局变量
window.$ = _$;
//写一个准备的方法
_$.onReady = function(fn){
//1实例化_$对象,真正的注册到window上
window.$ = function(){
return new _$(arguments);
};
//2执行传入的代码
fn();
//实现链式编程
//我们知道链式编程的写法:$().method1().method2();
_$.method(‘addEvent‘,function(){
}).method(‘setStyle‘,function(){
});
};
})(window);
//jQuery的调用一般这样写
$.onReady(function(){
$().addEvent().setStyle(); //addEvent setStyle
});
这时候我们已经大概写完了程序,就差一些具体的方法还没有实现而已
上面已经实现程序的总体框架已搭建完成了,下面我会把所有的代码写上
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<input id="inp" type="button" value="点击"/>
<script type="text/javascript">
(function(window,undefined){
//在大型程序开发中,一般使用‘_‘作为私有的对象
function _$(arguments){
//正则表达式用于判断是否为ID选择器
var idselector = /#\w+/;
//正则表达式匹配class选择器
var classSelector = /\.\w+/;
//加一个属性,用于接受所得到的元素
this.dom;
//test的用处
//1通过该值可以匹配字符串中是否存在于正则表达式相匹配的结果
//2返回值是布尔值,匹配为true,反之为false
if(idselector.test(arguments[0])){
if(typeof arguments[0] === ‘string‘){
//因为document.getElementById("ID") 获取元素
//id是不带#
var itemId = arguments[0].substring(1);
this.dom = document.getElementById(itemId);
}else{
throw new Error(‘arguments is error‘);
}
}else if(classSelector.test(arguments[0])){
}else{
//都不匹配就抛个错误
throw new Error(‘arguments is error‘);
}
};
//_$这是个类,也是一个函数,所以 也属于Function
Function.prototype.method = function(methodName,fn){
this.prototype[methodName] = fn;
//实现链式编程的关键
return this;
};
//在_$的原型对象中加一些公共的方法
_$.prototype ={
//还原构造器
constructor:_$,
//添加事件方法
addEvent:function(type,fn){
//给你得到的元素注册事件,要判断浏览器类型
if(window.addEventListener){ //FF
this.dom.addEventListener(type,fn);
}else if(window.attachEvent){ //IE
this.dom.attachEvent(‘on‘+type,fn);
}
//这里才是我们真正实现具体方法的链式编程
return this;
},
//改变样式
setStyle:function(prop,val){
this.dom.style[prop] = val;
//这里才是我们真正实现具体方法的链式编程
return this;
}
};
//window上先注册一个全局变量
window.$ = _$;
//写一个准备的方法
_$.onReady = function(fn){
//1实例化_$对象,真正的注册到window上
window.$ = function(){
return new _$(arguments);
};
//2执行传入的代码
fn();
//实现链式编程
//我们知道链式编程的写法:$().method1().method2();
_$.method(‘addEvent‘,function(){
}).method(‘setStyle‘,function(){
});
};
})(window);
//jQuery的调用一般这样写
$.onReady(function(){
//我们平常都是这样写的
$(‘#inp‘).addEvent(‘click‘,function(){
alert(‘我被点击了‘);
}).setStyle(‘backgroundColor‘,‘red‘);
});
//这样就实现了$.onReady这个方法了
</script>
</body>
</html>
本人才疏学浅,如若有不正确的地方,请大家指出,我会努力改过的。