前言:jQuery下的方法有很多,而且都很实用。比如each方法,我们可以$.each()这样去使用,也可以$('div').each()这样去使用,两者有什么区别呢?
-
var jQuery =
function( selector, context ) {
-
return
new jQuery.fn.init( selector, context, rootjQuery );
-
}
-
jQuery.each =
function(){}
前者是jQuery下的方法,可以直接使用,我们习惯性称为工具方法;
--------
-
jQuery.fn = jQuery.prototype = {
-
constructor: jQuery,
-
init:
function(){}
-
}
-
jQuery.fn.each =
function(){
-
-
}
后者是jQuery原型下的方法,需要实例jQuery对象后使用,我们习惯性称为jQuert实例对象方法。
一、模拟jQuery创建方法、扩展方法。
-
(
function(window,undefined){
-
var jQ =
function(selector){
-
return
new jQ.fn.init(selector);
-
};
-
jQ.fn = jQ.prototype = {
-
jquery:
'2.0.3',
//jquery版本号信息
-
constructor: jQ, //添加构造器属性
-
length:0, //初始length属性
-
selector:'', //初始selector属性
-
init: function(selector){
-
//初始化jQuery对象
-
},
-
toArray:
function(){},
-
get:
function(){},
-
pushStack:
function(){},
-
each:
function(){},
-
ready:
function(){},
-
slice:
function(){},
-
first:
function(){},
-
last:
function(){},
-
eq:
function(){},
-
map:
function(){},
-
end:
function(){},
-
push:
function(){},
-
sort:
function(){},
-
splice:
function(){}
-
};
-
jQ.fn.init.prototype = jQ.fn;
-
-
jQ.extend = jQ.fn.extend =
function(){
-
-
}
-
jQ.extend({
-
each:
function(){},
-
type:
function(){},
-
parseJSON:
function(){}
-
/*.............*/
-
});
-
jQ.fn.extend({
-
-
attr:
function(){},
-
removeAttr:
function(){},
-
addClass:
function(){},
-
removeClass:
function(){},
-
toggleClass:
function(){},
-
val:
function(){},
-
css:
function(){},
-
on:
function(){}
-
/*.............*/
-
});
-
-
window.$$ = jQ;
-
})(
window );
①、像jQ原型下有一些比较重要的方法,而且不会经常需要修改、优化,或者删除的方法。
②、而如果要继续添加、扩展方法。都是通过extend()去扩展方法。
-
jQ.extend = jQ.fn.extend =
function(){
-
-
}
③、扩展工具方法
-
jQ.extend({
-
each:
function(){},
-
type:
function(){},
-
parseJSON:
function(){}
-
/*.............*/
-
});
④、扩展jQuery对象方法
-
jQ.fn.extend({
-
attr:
function(){},
-
removeAttr:
function(){},
-
addClass:
function(){},
-
removeClass:
function(){},
-
toggleClass:
function(){},
-
val:
function(){},
-
css:
function(){},
-
on:
function(){}
-
/*.............*/
-
});
这样使得代码的更好维护,如果要添加方法只需要在extend中去操作,而不需要在核心代码中去操作。
二、extend扩展方法源码
在研究extend源码之前,来看看extend几种用法。
1、简单的说extend有四种用法:
①、扩展jquery工具方法
②、扩展jQuery实例对象方法
③、浅拷贝
④、深拷贝
2、进行细分的话,extend有以下几种情况
-
var obj1 = {
name:
'freddy',
hobit:[
"basketball"],
sex:
null };
-
var obj2 = {
age:
18 };
-
var obj3 = {};
-
var obj4 = {};
-
var obj5 = {};
-
-
$.extend({});
//①扩jQuery展工具方法
-
$.fn.extend({});
//②扩展jQuery实例对象方法
-
$.extend(obj3,obj1);
//③浅拷贝
-
$.extend(obj3,obj1,obj2);
//③浅拷贝多个对象
-
$.extend(
true,obj4,obj1);
//④深拷贝
-
$.extend(
true,obj4,obj1,obj2);
//④深拷贝多个对象
-
$.extend(obj5,{
name:
'nick'},{
age:
18});
//⑤扩展对象
-
console.log(obj3);
-
console.log(obj4);
-
console.log(obj5);
对于浅拷贝、深拷贝不熟悉的可以看看我以前的文章【JavaScript】对象引用、浅拷贝、深拷贝详解
3、直接上extend源码(这里的目标对象为“被扩展的对象”或者“拷贝别人”的对象)
-
jQuery.extend = jQuery.fn.extend =
function() {
-
var options, name, src, copy, copyIsArray, clone,
-
target =
arguments[
0] || {},
//设置第一个参数为目标对象
-
i =
1,
//i为1是浅拷贝情况下,被拷贝的对象是arguments[1],从二个参数开始
-
length =
arguments.length,
-
deep =
false;
//默认是浅拷贝
-
-
//$(true,arr4,arr1) || $(true,arr4,arr1,arr2);
-
if (
typeof target ===
"boolean" ) {
//深拷贝情况第一个参数为true,布尔类型
-
deep = target;
-
target =
arguments[
1] || {};
//目标对象变成第二个参数了
-
i =
2;
//被拷贝对象是arguments[2],从第三个参数开始
-
}
-
-
//看目标对象是否是对象
-
if (
typeof target !==
"object" && !jQuery.isFunction(target) ) {
-
target = {};
-
}
-
-
//$.extend({}) || $.fn.extend({}) 扩展方法
-
if ( length === i ) {
//只有一个参数的情况
-
target =
this;
//目标对象变成了$ 或者 $.fn
-
--i;
//i变成0
-
}
-
-
for ( ; i < length; i++ ) {
//for循环用于解决->拷贝多个对象的情况
-
-
if ( (options =
arguments[ i ]) !=
null ) {
//如果该参数对象不为undefined或null
-
-
for ( name
in options ) {
-
src = target[ name ];
//保存目标对象属性
-
copy = options[ name ];
//保存该属性的值
-
-
//如果出现$.extend(obj1,{ name:obj1 }); 跳过本次循环
-
if ( target === copy ) {
-
continue;
-
}
-
-
//如果该属性下的值是"对象自变量"或者"数组",就进行深拷贝
-
if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
//深拷贝
-
if ( copyIsArray ) {
//如果该属性下的值是"数组"
-
copyIsArray =
false;
-
clone = src && jQuery.isArray(src) ? src : [];
-
-
}
else {
//如果该属性下的值是"对象自变量"
-
clone = src && jQuery.isPlainObject(src) ? src : {};
-
}
-
-
target[ name ] = jQuery.extend( deep, clone, copy );
//然后进行递归操作
-
-
}
else
if ( copy !==
undefined ) {
//浅拷贝
-
target[ name ] = copy;
-
}
-
}
-
}
-
}
-
return target;
-
};
注释写上去之后,一些都明了了,也并没有什么难点。如果有不明白的地方可以下方留言。
三、扩展方法
-
<body>
-
<script src="https://cdn.bootcss.com/jquery/2.0.3/jquery.js">
</script>
-
<script>
-
$.extend({
-
freddy:
function(){
-
console.log(
'扩展jQuery工具方法');
-
}
-
});
-
$.fn.extend({
-
freddy:
function(){
-
console.log(
'扩展jQuery实例对象方法');
-
}
-
});
-
$.freddy();
-
$(
document).freddy();
-
</script>
-
</body>
运行结果
这样是不是很方面,就算不熟悉jquery源码,也能很快扩展出自己想要的方法。不过这里要注意的是,如果扩展的方法名如果跟jQuery原生的方法名重名(如css,attr),会发生我们扩展的方法覆盖了原生的jQuery方法。
原文发布时间为:2018年06月30日
原文作者:穆弘
本文来源CSDN如需转载请联系原作者