jQuery extend()详解及简单实例


Posted in jQuery onMay 06, 2017

jQuery extend()详解及简单实例

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

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

有些函数是这样使用的:

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

有些函数是这样使用的:

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

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

functionA(){ 
     
  } 
  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

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

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

functionA(){ 
    this.fun_f=function(){ 
        console.log("Iam in the constructor"); 
    }; 
} 
A.prototype.fun_p=function(){ 
    console.log("Iam in the prototype"); 
}; 
var a=newA(); 
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解析获取JSON数据
Apr 08 jQuery
jQuery使用ajax_动力节点Java学院整理
Jul 05 jQuery
jQuery选择器之子元素选择器详解
Sep 18 jQuery
一个有意思的鼠标点击文字特效jquery代码
Sep 23 jQuery
HTML5+JS+JQuery+ECharts实现异步加载问题
Dec 16 jQuery
jQuery序列化form表单数据为JSON对象的实现方法
Sep 20 jQuery
jQuery实现购物车的总价计算和总价传值功能
Nov 28 jQuery
jQuery实现动态添加和删除input框实例代码
Mar 26 jQuery
使用JQuery自动完成插件Auto Complete详解
Jun 18 jQuery
jQuery高级编程之js对象、json与ajax用法实例分析
Nov 01 jQuery
jQuery实现聊天对话框
Feb 08 jQuery
jquery实现简易验证插件封装
Sep 13 jQuery
jquery仿微信聊天界面
May 06 #jQuery
简单实现jQuery弹幕效果
May 06 #jQuery
jquery实现提示语淡入效果
May 05 #jQuery
Jquery获取radio选中的值
May 05 #jQuery
jQuery实现简单的抽奖游戏
May 05 #jQuery
jquery中each循环的简单回滚操作
May 05 #jQuery
jquery dataTable 获取某行数据
May 05 #jQuery
You might like
解析PHP中的内存管理,PHP动态分配和释放内存
2013/06/28 PHP
php+ajax导入大数据时产生的问题处理
2014/06/11 PHP
php+mysql结合Ajax实现点赞功能完整实例
2015/01/30 PHP
PHP载入图像imagecreatefrom_gif_jpeg_png系列函数用法分析
2016/11/14 PHP
浅谈JavaScript中面向对象技术的模拟
2006/09/25 Javascript
XP折叠菜单&amp;仿QQ2006菜单
2006/12/16 Javascript
iframe调用父页面函数示例详解
2014/07/17 Javascript
jQuery选择器源码解读(六):Sizzle选择器匹配逻辑分析
2015/03/31 Javascript
javascript相关事件的几个概念
2015/05/21 Javascript
AngularJS使用angular-formly进行表单验证
2015/12/27 Javascript
JavaScript html5 canvas绘制时钟效果
2016/03/01 Javascript
nodeJs爬虫获取数据简单实现代码
2016/03/29 NodeJs
JQuery统计input和textarea文字输入数量(代码分享)
2016/12/29 Javascript
关于vue.js v-bind 的一些理解和思考
2017/06/06 Javascript
详解Angular5路由传值方式及其相关问题
2018/04/28 Javascript
vue项目出现页面空白的解决方案
2019/10/31 Javascript
vue实现抽屉弹窗效果
2020/11/15 Javascript
[05:03]2018DOTA2亚洲邀请赛主赛事首日回顾
2018/04/04 DOTA
python中的字典详细介绍
2014/09/18 Python
Python提示[Errno 32]Broken pipe导致线程crash错误解决方法
2014/11/19 Python
python字符串的常用操作方法小结
2016/05/21 Python
python添加模块搜索路径和包的导入方法
2019/01/19 Python
Python代理IP爬虫的新手使用教程
2019/09/05 Python
python多进程(加入进程池)操作常见案例
2019/10/21 Python
django使用xadmin的全局配置详解
2019/11/15 Python
Python3标准库之functools管理函数的工具详解
2020/02/27 Python
HTML5的文档结构和新增标签完全解析
2017/04/21 HTML / CSS
html5 postMessage解决跨域、跨窗口消息传递方案
2016/12/20 HTML / CSS
html5简单示例_动力节点Java学院整理
2017/07/07 HTML / CSS
什么情况下你必须要把一个类定义为abstract的
2013/01/06 面试题
linux面试题参考答案(7)
2012/10/29 面试题
大学生自荐书范文
2013/12/10 职场文书
2014工程部年度工作总结
2014/12/17 职场文书
举起手来观后感
2015/06/09 职场文书
锦旗赠语
2015/06/23 职场文书
结婚纪念日感言
2015/08/01 职场文书