jQuery源码解读之extend()与工具方法、实例方法详解


Posted in jQuery onMarch 30, 2017

本文实例讲述了jQuery源码解读之extend()与工具方法、实例方法。分享给大家供大家参考,具体如下:

使用jQuery的时候会发现,jQuery中有的函数是这样使用的:

$.get();
$.post();
$.getJSON();

有些函数是这样使用的:

$('div').css();
$('ul').find('li');

有些函数是这样使用的:

$('li').each(callback);
$.each(lis,callback);

这里涉及到两个概念:工具方法与实例方法。通常我们说的工具方法是指无需实例化就可以调用的函数,如第一段代码;实例方法是必须实例化对象以后才可以调用的函数,如第二段代码。jQuery中很多方法既是实例方法也是工具方法,只是调用方式略有不同,如第三段代码。为了更清晰解释JavaScript中的工具方法与实例方法,进行如下测试。

function A(){
}
A.prototype.fun_p=function(){console.log("prototpye");};
A.fun_c=function(){console.log("constructor");};
var a=new A();
A.fun_p();//A.fun_p is not a function
A.fun_c();//constructor
a.fun_p();//prototpye
a.fun_c();//a.fun_c is not a function

通过以上测试可以得出结论,在原型中定义的是实例方法,在构造函数中直接添加的是工具方法;实例方法不能由构造函数调用,同理,工具方法也不能由实例调用。

当然实例方法不仅可以在原型中定义,有以下三种定义方法:

function A(){
    this.fun_f=function(){
        console.log("Iam in the constructor");
    };
}
A.prototype.fun_p=function(){
    console.log("Iam in the prototype");
};
var a=new A();
a.fun_f();//Iam in the constructor
a.fun_i=function(){
    console.log("Iam in the instance");
};
a.fun_i();//Iam in the instance
a.fun_p();//Iam in the prototype

这三种方式的优先级为:直接定义在实例上的变量的优先级要高于定义在“this”上的,而定义在“this”上的又高于 prototype定义的变量。即直接定义在实例上的变量会覆盖定义在“this”上和prototype定义的变量,定义在“this”上的会覆盖prototype定义的变量。

下面看jQuery中extend()方法源码:

jQuery.extend = jQuery.fn.extend = function() {
    var options,name, src, copy, copyIsArray, clone,
        target= arguments[0] || {},
        i =1,
        length= arguments.length,
        deep= false;
    // Handle adeep copy situation
    if ( typeoftarget === "boolean" ) {
        deep= target;
        //Skip the boolean and the target
        target= arguments[ i ] || {};
        i++;
    }
    // Handlecase when target is a string or something (possible in deep copy)
    if ( typeoftarget !== "object" && !jQuery.isFunction(target) ) {
        target= {};
    }
    // ExtendjQuery itself if only one argument is passed
    if ( i ===length ) {
        target= this;
        i--;
    }
    for ( ; i< length; i++ ) {
        //Only deal with non-null/undefined values
        if ((options = arguments[ i ]) != null ) {
            //Extend the base object
            for( name in options ) {
                src= target[ name ];
                copy= options[ name ];
                //Prevent never-ending loop
                if( target === copy ) {
                   continue;
                }
                //Recurse if we're merging plain objects or arrays
                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 : {};
                   }
                   //Never move original objects, clone them
                   target[name ] = jQuery.extend( deep, clone, copy );
                //Don't bring in undefined values
                }else if ( copy !== undefined ) {
                   target[name ] = copy;
                }
            }
        }
    }
    // Returnthe modified object
    return target;
};

(1)首先,jQuery和其原型中extend()方法的实现使用的同一个函数。

(2)当extend()中只有一个参数的时候,是为jQuery对象添加插件。在jQuery上扩展的叫做工具方法,在jQuery.fn(jQuery原型)中扩展的是实例方法,即使在jQuery和原型上扩展相同名字的函数也可以,使用jQuery对象会调用工具方法,使用jQuery()会调用实例方法。

(3)当extend()中有多个参数时,后面的参数都扩展到第一个参数上。

var a={};
$.extend(a,{name:"hello"},{age:10});
console.log(a);//Object{name: "hello", age: 10}

(4)浅拷贝(默认):

var a={};
varb={name:"hello"};
$.extend(a,b);
console.log(a);//Object{name: "hello"}
a.name="hi";
console.log(b);//Object{name: "hello"}

b不受a影响,但是如果b中一个属性为对象:

var a={};
varb={name:{age:10}};
$.extend(a,b);
console.log(a.name);//Object{age: 10}
a.name.age=20;
console.log(b.name);//Object{age: 20}

由于浅拷贝无法完成,则b.name会受到a的影响,这时我们往往希望深拷贝。

深拷贝:

var a={};
varb={name:{age:10}};
$.extend(true,a,b);
console.log(a.name);//Object{age: 10}
a.name.age=20;
console.log(b.name);//Object{age: 10}

b.name不受a的影响。

var a={name:{job:"Web Develop"}};
var b={name:{age:10}};
$.extend(true,a,b);
console.log(a.name);//age: 10 job: "Web Develop"
//b.name没有覆盖a.name.job。

希望本文所述对大家jQuery程序设计有所帮助。

jQuery 相关文章推荐
jQuery使用unlock.js插件实现滑动解锁
Apr 04 jQuery
jQuery+PHP+Mysql实现抽奖程序
Apr 12 jQuery
jquery单击文字或图片内容放大并居中显示
Jun 23 jQuery
jQuery扇形定时器插件pietimer使用方法详解
Jul 18 jQuery
jQuery实现的文字逐行向上间歇滚动效果示例
Sep 06 jQuery
jQuery实现html双向绑定功能示例
Oct 09 jQuery
jQuery实现动态控制页面元素的方法分析
Dec 20 jQuery
jQuery图片查看插件Magnify开发详解
Dec 25 jQuery
用jquery获取select标签中选中的option值及文本的示例
Jan 25 jQuery
jquery根据name取得select选中的值实例(超简单)
Jan 25 jQuery
jQuery实现的淡入淡出图片轮播效果示例
Aug 29 jQuery
Jquery使用each函数实现遍历及数组处理
Jul 14 jQuery
jQuery实现Select下拉列表进行状态选择功能
Mar 30 #jQuery
基于jquery实现二级联动效果
Mar 30 #jQuery
jquery中关于bind()方法的使用技巧分享
Mar 30 #jQuery
如何编写jquery插件
Mar 29 #jQuery
jQuery日程管理控件glDatePicker用法详解
Mar 29 #jQuery
jQuery实现简单漂亮的Nav导航菜单效果
Mar 29 #jQuery
jQuery实现的手风琴侧边菜单效果
Mar 29 #jQuery
You might like
PHP生成静态页面详解
2006/11/19 PHP
PHP session文件独占锁引起阻塞问题解决方法
2015/05/12 PHP
PHP5.5迭代生成器用法实例详解
2016/03/16 PHP
PHP实现的文件操作类及文件下载功能示例
2016/12/24 PHP
深入理解JavaScript系列(14) 作用域链介绍(Scope Chain)
2012/04/12 Javascript
PHP+jQuery+Ajax实现多图片上传效果
2015/03/14 Javascript
Javascript实现计算个人所得税
2015/05/10 Javascript
JS实现常见的TAB、弹出层效果(TAB标签,斑马线,遮罩层等)
2015/10/08 Javascript
jquery.cookie实现的客户端购物车操作实例
2015/12/24 Javascript
JavaScript 数组的深度复制解析
2016/11/02 Javascript
JavaScript中使用webuploader实现上传视频功能(demo)
2017/04/10 Javascript
详解Vue基于 Nuxt.js 实现服务端渲染(SSR)
2018/04/05 Javascript
layui实现文件或图片上传记录
2018/08/28 Javascript
Element UI框架中巧用树选择器的实现
2018/12/12 Javascript
JavaScript实现的弹出遮罩层特效经典示例【基于jQuery】
2019/07/10 jQuery
jQuery实现简单三级联动效果
2020/09/05 jQuery
python改变日志(logging)存放位置的示例
2014/03/27 Python
python利用beautifulSoup实现爬虫
2014/09/29 Python
初步解析Python中的yield函数的用法
2015/04/03 Python
Python入门之三角函数全解【收藏】
2017/11/08 Python
pyttsx3实现中文文字转语音的方法
2018/12/24 Python
pandas DataFrame 删除重复的行的实现方法
2019/01/29 Python
python-sys.stdout作为默认函数参数的实现
2020/02/21 Python
Python 多线程共享变量的实现示例
2020/04/17 Python
详解pyinstaller生成exe的闪退问题解决方案
2020/06/19 Python
浅谈sklearn中predict与predict_proba区别
2020/06/28 Python
Python如何使用神经网络进行简单文本分类
2021/02/25 Python
详解基于canvas的视频遮罩插件
2018/01/04 HTML / CSS
银行个人求职自荐信范文
2013/12/16 职场文书
村级环境卫生整治方案
2014/05/04 职场文书
诚信的演讲稿范文
2014/05/12 职场文书
广播节目策划方案
2014/05/23 职场文书
担保贷款承诺书
2015/04/30 职场文书
审查起诉阶段律师意见书
2015/05/19 职场文书
创业计划之特色精品店
2019/08/12 职场文书
Python使用plt.boxplot()函数绘制箱图、常用方法以及含义详解
2022/08/14 Python