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 Ajax自定义分页组件(jquery.loehpagerv1.0)实例详解
May 01 jQuery
jQuery实现返回顶部按钮和scroll滚动功能[带动画效果]
Jul 05 jQuery
jQuery实现的表格前端排序功能示例
Sep 18 jQuery
jquery ajax异步提交表单数据的方法
Oct 27 jQuery
jQuery实现的点击按钮改变样式功能示例
Jul 21 jQuery
JQuery模拟实现网页中自定义鼠标右键菜单功能
Nov 14 jQuery
jQuery利用FormData上传文件实现批量上传
Dec 04 jQuery
jQuery简单实现根据日期计算星期几的方法
Jan 09 jQuery
jQuery选择器之基本选择器用法实例分析
Feb 19 jQuery
jQuery--遍历操作实例小结【后代、同胞及过滤】
May 22 jQuery
jQuery使用jsonp实现百度搜索的示例代码
Jul 08 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
Smarty结合Ajax实现无刷新留言本实例
2007/01/02 PHP
PHP反转字符串函数strrev()函数的用法
2012/02/04 PHP
php数字游戏 计算24算法
2012/06/10 PHP
利用php获取服务器时间的实现代码
2013/06/07 PHP
PHP正则表达式 /i, /is, /s, /isU等介绍
2014/10/23 PHP
关于php中一些字符串总结
2016/05/05 PHP
PHP+MySql实现一个简单的留言板
2020/07/19 PHP
JavaScript获取GridView选择的行内容
2009/04/14 Javascript
根据鼠标的位置动态的控制层的位置
2009/11/24 Javascript
JavaScript和CSS交互的方法汇总
2014/12/02 Javascript
js+html5获取用户地理位置信息并在Google地图上显示的方法
2015/06/05 Javascript
详解微信小程序入门五: wxml文件引用、模版、生命周期
2017/01/20 Javascript
微信小程序 刷新上拉下拉不会断详细介绍
2017/05/11 Javascript
js的函数的按值传递参数(实例讲解)
2017/11/16 Javascript
nodejs中方法和模块用法示例
2018/12/24 NodeJs
[01:00] DOTA2英雄背景故事第五期之重力引力法则谜团
2020/07/16 DOTA
Python中的字典遍历备忘
2015/01/17 Python
Python的网络编程库Gevent的安装及使用技巧
2016/06/24 Python
python制作爬虫爬取京东商品评论教程
2016/12/16 Python
Python 加密的实例详解
2017/10/09 Python
python使用opencv实现马赛克效果示例
2019/09/28 Python
python3反转字符串的3种方法(小结)
2019/11/07 Python
python实现IOU计算案例
2020/04/12 Python
keras .h5转移动端的.tflite文件实现方式
2020/05/25 Python
CSS3实现背景透明文字不透明的示例代码
2018/06/25 HTML / CSS
外贸销售员求职的自我评价
2013/11/23 职场文书
写给女朋友的道歉信
2014/01/12 职场文书
电大本科自我鉴定
2014/02/05 职场文书
幼儿园教师演讲稿
2014/05/06 职场文书
银行会计主管岗位职责
2014/10/01 职场文书
财务总监岗位职责
2015/02/03 职场文书
2016自主招生教师推荐信范文
2015/03/23 职场文书
母亲节主题班会
2015/08/14 职场文书
Oracle设置DB、监听和EM开机启动的方法
2021/04/25 Oracle
python中opencv实现图片文本倾斜校正
2021/06/11 Python
Mysql中常用的join连接方式
2022/05/11 MySQL