extend方法被挂载在了jQuery和jQuery.fn两个不同对象上,但是两者的内部代码实现确实相同的,只是功能不太一样。
<1>jQuery.extend(object)
用于将一个或多个对象的内容合并到目标对象。该函数可以将一个或多个对象的成员属性和方法复制到指定的对象上。该函数属于全局jQuery对象。
jQuery.extend( target [, object1 ] [, objectN ] ),extend方法需要至少传入一个参数,第一个必需,后面的都是可选参数。若传给extend是两个或两个以上的参数都是对象类型,那么就会把后面所有对象的内容合并给target(第一个对象)上。
<2>jQuery.fn.extend(object)
用于为jQuery扩展一个或多个实例属性和方法(主要用于扩展方法)。jQuery.fn是jQuery的原型对象,其extend()方法用于为jQuery的原型添加新的属性和方法。这些方法可以在jQuery实例对象上调用。该函数属于jQuery的原型对象(jQuery.fn)。
例如:
function getOpt(option){ var _default = { name : 'wenzi', age : '25', sex : 'male' } $.extend(_default, option);` return _default; } /*---console.log(JSON.stringify(getOpt()))---*/ getOpt(); // {name: "wenzi", age: "25", sex: "male"} getOpt({name:'bing'}); // {name: "bing", age: "25", sex: "male"} getOpt({name:'bing', age:36, sex:'female'}); // {name: "bing", age: 36, sex: "female"} function getOpt(target, obj1, obj2, obj3){ $.extend(target, obj1, obj2, obj3); return target; } //注:$.extend()返回修改后的第一个参数的值 var _default = { name : 'wenzi', age : '25', sex : 'male' } var obj1 = { name : 'obj1' } var obj2 = { name : 'obj2', age : '36' } var obj3 = { age : '67', sex : {'error':'sorry, I dont\'t kown'} } getOpt(_default, obj1, obj2, obj3); // {name: "obj2", age: "67", sex: {error: "sorry, I dont't kown"}}结果:属性值永远是最后一个属性的值,但是这样_default就会被修改了。当然很多时候为了传入的参数不被修改,通常都会这么做,即传个空对象 $.extend({},target, obj1, obj2, obj3);则合并的目标对象即为{},不会去修改参数对象了。
$.extend()其实只有一个参数是必须的。如果只有一个参数提供给$.extend(),这意味着目标参数被省略。在这种情况下,jQuery对象本身被默认为目标对象[后面源码中看了就知道了]。这样,我们可以在jQuery的命名空间下添加新的功能。
例如:
$.extend({ _name : 'hello world', _getName : function(){ return this._name; } }) $._name; // hello world $._getName(); // hello world //这样我们就为jQuery扩展了_name属性和_getName方法。3、深度拷贝和浅度拷贝
例如:
var obj = {name:'星辰', sex:'male'}; var obj1 = obj; // 赋值 obj1.name = '小星辰'; console.log(obj.name); // 小星辰我们修改了obj1中的name值,结果obj中的值也跟着发生了变化,这是为什么呢。其实这就是浅度拷贝:这仅仅是将obj对象的引用地址简单的复制了一份给予变量 obj1,而并不是将真正的对象克隆了一份,因此obj和obj1指向的都是同一个地址。当修改obj1的属性或给obj1添加新属性时,obj都会受到影响。
例如:
var s = 'hello'; var t = s; t = 'world'; console.log(s); // hello深度拷贝就不是拷贝引用地址,而是实实在在的复制一份新对象给新的变量。在上面使用$.extend()中,都是使用的浅度拷贝,因此若后面的参数值是object类型或array类型,修改_default(target)的值,就会影响后面参数的值。
如我们使用getOpt(_default, obj1, obj2, obj3);得到的_default值是{name: “obj2”, age: “67”, sex: {error: “sorry, I dont’t kown”}},可是若:_default.sex.error = 'hello world';那么obj3.sex.error也会跟着修改,因为obj3.sex是一个object类型。
不过$.extend()也提供了深度拷贝的方法:jQuery.extend( [deep ], target, object1 [, objectN ] )。若第一个参数是boolean类型,且值是true,那么就会把第二个参数作为目标参数进行合并。
例如:
var obj = {name:'星辰', score:80}; var obj1 = {score:{english:80, math:90}} $.extend(true, obj, obj1); obj.score.english = 10; console.log(obj.score.english); // 10 console.log(obj1.score.english); // 80 这里并没有因为obj的改变而改变
jquery为开发插件提供了两个方法.jQuery.extend(object); 为扩展jQuery类本身,为自身添加新的方法。jQuery.fn.extend(object);给jQuery对象添加方法。
在源码中我们看到jQuery.extend = jQuery.fn.extend = function(){}。也就是说$.extend()与$.fn.extend()共用的是同一个函数体,所有的操作都是一样的,只不过两个extend使用的对象不同罢了。