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+ThinkPHP+Ajax实现即时消息提醒功能实例代码
Mar 21 jQuery
jQuery轻松实现无缝轮播效果
Mar 22 jQuery
关于jQuery中fade(),show()起始位置的一点小发现
Apr 25 jQuery
jQuery返回定位插件详解
May 15 jQuery
jQuery Ajax使用FormData上传文件和其他数据后端web.py获取
Jun 11 jQuery
jquery登录的异步验证操作示例
May 09 jQuery
jQuery zTree树插件的使用教程
Aug 16 jQuery
jquery添加div实现消息聊天框
Feb 08 jQuery
jQuery实现的解析本地 XML 文档操作示例
Apr 30 jQuery
JavaScript或jQuery 获取option value值方法解析
May 12 jQuery
jQuery实现视频展示效果
May 30 jQuery
Jquery滑动门/tab切换实现方法完整示例
Jun 05 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
第八节--访问方式
2006/11/16 PHP
Android ProgressBar进度条和ProgressDialog进度框的展示DEMO
2013/06/19 PHP
php计算当前程序执行时间示例
2014/04/24 PHP
php版本的cron定时任务执行器使用实例
2014/08/19 PHP
PHP多态代码实例
2015/06/26 PHP
PHP join()函数用法与实例讲解
2019/03/11 PHP
通过Unicode转义序列来加密,按你说的可以算是混淆吧
2007/05/06 Javascript
js 数组去重的四种实用方法
2014/09/09 Javascript
jQuery 复合选择器应用的几个例子
2014/09/11 Javascript
jQuery对JSON数据进行排序输出的方法
2015/06/24 Javascript
node.js 动态执行脚本
2016/06/02 Javascript
Jquery获取当前城市的天气信息
2016/08/05 Javascript
一步一步封装自己的HtmlHelper组件BootstrapHelper(三)
2016/09/14 Javascript
JS实现字符串转驼峰格式的方法
2016/12/16 Javascript
从零开始学习Node.js系列教程五:服务器监听方法示例
2017/04/13 Javascript
js字符串与Unicode编码互相转换
2017/05/17 Javascript
JavaScript如何获取到导航条中HTTP信息
2017/10/10 Javascript
360doc网站不登录就无法复制内容的解决方法
2018/01/27 Javascript
vue-cli 引入、配置axios的方法
2018/05/08 Javascript
python脚本实现分析dns日志并对受访域名排行
2014/09/18 Python
Python中subprocess模块用法实例详解
2015/05/20 Python
Python实现的十进制小数与二进制小数相互转换功能
2017/10/12 Python
500行代码使用python写个微信小游戏飞机大战游戏
2019/10/16 Python
python 给图像添加透明度(alpha通道)
2020/04/09 Python
python实现IOU计算案例
2020/04/12 Python
Python json解析库jsonpath原理及使用示例
2020/11/25 Python
英国美发和美容产品商城:HQhair
2019/02/08 全球购物
Shopping happy life西班牙:以最优惠的价格提供最好的时尚配饰
2020/03/13 全球购物
高职助产应届生自荐信
2013/09/24 职场文书
应届生体育教师自荐信
2013/10/03 职场文书
酒店管理专业毕业生求职自荐信
2014/04/28 职场文书
教师师德师风自我剖析材料
2014/09/29 职场文书
关于@OnetoMany关系映射的排序问题,使用注解@OrderBy
2021/12/06 Java/Android
Minikube搭建Kubernetes集群
2022/03/31 Servers
Java界面编程实现界面跳转
2022/06/16 Java/Android
maven 解包依赖项中的文件的解决方法
2022/07/15 Java/Android