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 Easyui Treegrid实现显示checkbox功能
Aug 08 jQuery
基于jQuery实现的单行公告活动轮播效果
Aug 23 jQuery
jQuery实现可兼容IE6的淡入淡出效果告警提示功能示例
Sep 20 jQuery
jQuery简单实现对数组去重及排序操作实例
Oct 31 jQuery
jquery 给动态生成的标签绑定事件的几种方法总结
Feb 24 jQuery
jQuery实现判断上传图片类型和大小的方法示例
Apr 11 jQuery
jQuery+CSS实现的标签页效果示例【测试可用】
Aug 14 jQuery
jQuery 点击获取验证码按钮及倒计时功能
Sep 20 jQuery
jQuery pjax 应用简单示例
Sep 20 jQuery
jQuery实现的导航条点击后高亮显示功能示例
Mar 04 jQuery
jQuery实现轮播图源码
Oct 23 jQuery
jQuery实现的移动端图片缩放功能组件示例
May 01 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/10/09 PHP
php下使用SMTP发邮件的代码
2008/01/10 PHP
dedecms函数分享之获取某一栏目所有子栏目
2014/05/19 PHP
PHP使用range协议实现输出文件断点续传代码实例
2014/07/04 PHP
PHP自定义错误处理的方法分析
2018/12/19 PHP
js的闭包的一个示例说明
2008/11/18 Javascript
jquery 学习笔记 传智博客佟老师附详细注释
2020/09/12 Javascript
实现png图片和png背景透明(支持多浏览器)的方法
2009/09/08 Javascript
JavaScript在IE和Firefox(火狐)的不兼容问题解决方法小结
2010/04/13 Javascript
Jquery AJAX 用于计算点击率(统计)
2010/06/30 Javascript
jQuery之自动完成组件的深入解析
2013/06/19 Javascript
JavaScript简单修改窗口大小的方法
2015/08/03 Javascript
浅析JavaScript声明变量
2015/12/21 Javascript
基于jquery实现智能提示控件intellSeach.js
2016/03/17 Javascript
JavaScript中用let语句声明作用域的用法讲解
2016/05/20 Javascript
实例讲解JavaScript中的this指向错误解决方法
2016/06/13 Javascript
JS中判断null的方法分析
2016/11/21 Javascript
微信小程序(六):列表上拉加载下拉刷新示例
2017/01/13 Javascript
Vue使用枚举类型实现HTML下拉框步骤详解
2018/02/05 Javascript
JS实现的base64加密解密操作示例
2018/04/18 Javascript
vue中的过滤器实例代码详解
2019/06/06 Javascript
[48:23]DOTA2上海特级锦标赛主赛事日 - 4 败者组第四轮#1COL VS EG第一局
2016/03/05 DOTA
Python EOL while scanning string literal问题解决方法
2020/09/18 Python
Python使用xlrd模块操作Excel数据导入的方法
2015/05/26 Python
在Python的一段程序中如何使用多次事件循环详解
2017/09/07 Python
Python中类的初始化特殊方法
2017/12/01 Python
Python无损音乐搜索引擎实现代码
2018/02/02 Python
Python使用pandas对数据进行差分运算的方法
2018/12/22 Python
使用Python给头像加上圣诞帽或圣诞老人小图标附源码
2019/12/25 Python
时尚、社区、科技:SEVENSTORE
2019/04/26 全球购物
制药工程专业个人求职自荐信
2014/01/25 职场文书
主管竞聘书范文
2014/03/31 职场文书
文员求职信
2014/07/15 职场文书
廉政承诺书
2015/01/19 职场文书
创业计划书之都市休闲农庄
2019/12/28 职场文书
MySQL常见优化方案汇总
2022/01/18 MySQL