javascript中的深复制方法一:jQuery中的extend方法

来源:互联网 发布:数据库er图讲解 编辑:程序博客网 时间:2024/05/22 03:42

extend语法

jQuery中的extend方法写插件常用到的方法:

jQuery.extend([deep], target, object1, [objectN])

概述

用一个或多个其他对象来扩展一个对象,返回被扩展的对象。

如果不指定target,则给jQuery命名空间本身进行扩展。这有助于插件作者为jQuery增加新方法。 如果第一个参数设置为true,则jQuery返回一个深层次的副本,递归地复制找到的任何对象。否则的话,副本会与原对象共享结构。 未定义的属性将不会被复制,然而从对象的原型继承的属性将会被复制。

参数

[deep],target,object1,[objectN]

Boolean,Object,Object,Object

注意:

deep参数只有两种情况:true(深复制)或者无(浅复制)。

deep参数为true的时候,若参数是两个或者两个以上,则是深复制。若参数是一个则是添加新函数。

没有deep参数的时候,若参数是一个的时候,功能是添加新函数。若参数是两个或者两个以上的时候是浅复制。

由jQuery.extend源码可知,deep参数默认是false,但是在调用extend的时候如果不是深复制则不能将false传给deep,否则会将false当成target。

特别注意:

为了减少麻烦,使用jQuery.extend实现浅复制的时候,不要使用jQuery.extend(false, object1, object2, [objectN])的形式,

因为此时目标参数target不是object1,extend函数的返回值不是object1,而是将第一个参数false转换成对象{},并且作为目标参数,

所以extend对object1不会进行修改。jQuery.extend(false, object1, object2, [objectN])的形式等效于jQuery.extend({}, object1, object2, [objectN]),target={}。

deep:如果设为true,则递归合并

target:待修改对象。

object1:待合并到第一个对象的对象。

objectN:待合并到第一个对象的对象。


target,[object1],[objectN]

Object,Object,Object

注意:

这里是浅复制

target:一个对象,如果附加的对象被传递给这个方法将那么它将接收新的属性,如果它是唯一的参数将扩展jQuery的命名空间。

object1:待合并到第一个对象的对象。

objectN:待合并到第一个对象的对象。


能实现的功能

1:将两个或多个对象的内容合并到第一个对象

jQuery.extend( target [, object1 ] [, objectN ] )

         extend方法需要至少传入一个参数,第一个必需,后面的都是可选参数。若传给extend是两个或两个以上的参数都是对象类型,那么就会把后面所有对象的内容合并给target(第一个对象)上。

2:为jQuery添加新函数

jQuery.extend(target)

         如果只有一个参数,在这种情况下,jQuery对象本身被默认为目标对象。这样,我们可以在jQuery的命名空间下添加新的功能。这对于插件开发者希望向 jQuery 中添加新函数时是很有用的。

jQuery源码解释

// 为与源码的下标对应上,我们把第一个参数称为`第0个参数`,依次类推jQuery.extend = jQuery.fn.extend = function() { var options, name, src, copy, copyIsArray, clone, target = arguments[0] || {}, // 默认第0个参数为目标参数 i = 1, // i表示从第几个参数凯斯想目标参数进行合并,默认从第1个参数开始向第0个参数进行合并 length = arguments.length, deep = false; // 默认为浅度拷贝  // 判断第0个参数的类型,若第0个参数是boolean类型,则获取其为true还是false // 同时将第1个参数作为目标参数,i从当前目标参数的下一个 // Handle a deep copy situation if ( typeof target === "boolean" ) { deep = target;  // Skip the boolean and the target target = arguments[ i ] || {}; i++; }  // 判断目标参数的类型,若目标参数既不是object类型,也不是function类型,则为目标参数重新赋值  // Handle case when target is a string or something (possible in deep copy) if ( typeof target !== "object" && !jQuery.isFunction(target) ) { target = {}; }  // 若目标参数后面没有参数了,如$.extend({_name:'wenzi'}), $.extend(true, {_name:'wenzi'}) // 则目标参数即为jQuery本身,而target表示的参数不再为目标参数 // Extend jQuery itself if only one argument is passed if ( i === length ) { target = this; i--; }  // 从第i个参数开始 for ( ; i < length; i++ ) { // 获取第i个参数,且该参数不为null和undefind,在js中null和undefined,如果不区分类型,是相等的,null==undefined为true, // 因此可以用null来同时过滤掉null和undefind // 比如$.extend(target, {}, null);中的第2个参数null是不参与合并的 // Only deal with non-null/undefined values if ( (options = arguments[ i ]) != null ) {   // 使用for~in获取该参数中所有的字段 // Extend the base object for ( name in options ) { src = target[ name ]; // 目标参数中name字段的值 copy = options[ name ]; // 当前参数中name字段的值  // 若参数中字段的值就是目标参数,停止赋值,进行下一个字段的赋值 // 这是为了防止无限的循环嵌套,我们把这个称为,在下面进行比较详细的讲解 // Prevent never-ending loop if ( target === copy ) {  continue; }  // 若deep为true,且当前参数中name字段的值存在且为object类型或Array类型,则进行深度赋值 // Recurse if we're merging plain objects or arrays if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {  // 若当前参数中name字段的值为Array类型  // 判断目标参数中name字段的值是否存在,若存在则使用原来的,否则进行初始化  if ( copyIsArray ) {  copyIsArray = false;  clone = src && jQuery.isArray(src) ? src : [];   } else {  // 若原对象存在,则直接进行使用,而不是创建  clone = src && jQuery.isPlainObject(src) ? src : {};  }   // 递归处理,此处为2.2  // Never move original objects, clone them    target[ name ] = jQuery.extend( deep, clone, copy );  // deep为false,则表示浅度拷贝,直接进行赋值 // 若copy是简单的类型且存在值,则直接进行赋值 // Don't bring in undefined values } else if ( copy !== undefined ) {  // 若原对象存在name属性,则直接覆盖掉;若不存在,则创建新的属性  target[ name ] = copy; } } } }  // 返回修改后的目标参数 // Return the modified object return target;};


原创粉丝点击