下面我们来模拟一下 jQuery 底层的链式调用:
其实核心就一点:return this;
第一步:建立块级作用域
/*
建立块级作用域,作用:
1、程序启动的时候,块级作用域里的代码就会执行
/2、其内部成员变量 外部无法访问 (除了不加 var 修饰的变量)
*/
(function(window, undefined){
/*
为什么会有个undefined?
jQuery作者是通过这种方式创建另一个值为undefined的变量,取名叫undefined(undefined是可以作为标识符,用作变量名的呦)。
*/
})(window);// 将全局的window对象作为参数传入,方便我们直接调用window,应该是为了提高效率
(function(window, undefined){
// 大型程序的开发,一般使用 ‘_’ 作为私有对象
function _$(arguments){
}
// window 上注册一个全局变量,与外界产生关系
window.$ = _$;
// 写一个准备的方法
_$.onReady = function(fn){ // 传入一个函数
// 实例化一个 _$ 对象,真正的注册到window上
window.$ = function(){
return new _$(arguments);
};
fn();
};
})(window);
第三步:完善 $ 对象的方法
(function(window, undefined){
function _$(arguments){
// 这里我们只通过 id选择器 这一种方式来获取节点
// 声明一个节点属性 dom
this.dom;
// 判断:如果传入的参数是一个以 '#' 开头的字符串,则为 id选择器
if(typeof arguments[0] === 'string' && arguments[0].charAt(0) === '#'){
this.dom = document.getElementById(arguments[0].substring(1));
}
}
// 为 _$ 类添加原型方法:1、click; 2、setStyle;
_$.prototype = {
// 重要:单体的构造器为Object,因此必须将构造器更改为—_$
constructor : _$,
click : function(fn){
this.dom.onclick = function(e){
fn(e);
};
return this; // 关键:实现链式调用
},
setStyle : function(obj){ // obj 是一个单体对象(obj = {})
for(var prop in obj){
this.dom.style[prop] = obj[prop];
}
return this; // 关键:实现链式调用
}
};
window.$ = _$;
_$.onReady = function(fn){
window.$ = function(){
return new _$(arguments);
};
fn();
};
})(window);
// 测试:<div id="div1">我是DIV</div>
$.onReady(function(){
$('#div1').click(function(){
alert('我被点击了!');
}).setStyle({
width:'200px',
height:'50px',
padding: '10px',
background:'red',
color:'#fff'
});
});