引用对象深度赋值
var cloneObj = function(obj){ var str, newobj = obj.constructor === Array ? [] : {}; if(typeof obj !== 'object'){ return; } else if(window.JSON){ str = JSON.stringify(obj), //系列化对象 newobj = JSON.parse(str); //还原 } else { for(var i in obj){ newobj[i] = typeof obj[i] === 'object' ? cloneObj(obj[i]) : obj[i]; } } return newobj; };
一、jQuery.merge( first, second )
first第一个用来合并的数组,元素是第二数组加进来的。 second第二个数组合并到第一,保持不变。
$.merge()
函数是破坏性的。它改变了从第二个添加项目到第一个参数。 如果您需要原始的第一个数组,请在调用$.merge()
前拷贝一个出来。var newArray = $.merge([], oldArray); var first = ['a','b','c']; var second = ['d','e','f']; var result=$.merge( $.merge([],first), second); function (first, second) { var l = second.length, i = first.length, j = 0; if (typeof l === "number") { for (; j < l; j++) { first[i++] = second[j]; } } else { while (second[j] !== undefined) { first[i++] = second[j++]; } } first.length = i; return first; }
二、JavaScript concat() 方法
var aa = [].concat([12]),bb = [].concat([12]); aa==bb//false
三、
js对象浅拷贝,简单的赋值就是浅拷贝。因为对象和数组在赋值的时候都是引用传递。赋值的时候只是传递一个指针。jQuery的API手册中,extend方法挂载在jQuery和jQuery.fn两个不同对象上方法,但在jQuery内部代码实现的是相同的,只是功能却不太一样
且看官方给出解释:
jQuery.extend(): Merge the contents of two or more objects together into the first object.(把两个或者更多的对象合并到第一个当中);
jQuery.fn.extend():Merge the contents of an object onto the jQuery prototype to provide new jQuery instance methods.(把对象挂载到jQuery的prototype属性,来扩展一个新的jQuery实例方法)
简单理解两者区别:
jQuery.extend(object); 为扩展jQuery类本身,为自身添加新的方法。
jQuery.fn.extend(object);给jQuery对象添加方法。
(1) jQuery.extend( target [, object1 ] [, objectN ] )
合并object1, objectN到target对象,如果只有一个参数,则该target对象会被合并到jQuery对象中
var object1 = {apple: 0,banana: { weight: 52, price: 100 },cherry: 97}; var object2 = {banana: { price: 200 },durian: 100}; $.extend( object1); $.extend( object1, object2 );
(2) jQuery.extend( [deep ], target, object1 [, objectN ] )
深度复制合并对象,第一个参数是boolean类型的true时,将object1, objectN深度复制后合并到target中;关于深度复制,是将除null, undefined,window对象,dom对象,通过继承创建的对象外的其它对象克隆后保存到target中;
深度与非深度复制区别是,深度复制的对象中如果有复杂属性值(如数组、函数、json对象等),那将会递归属性值的复制,合并后的对象修改属性值不影响原对象,如下面例子:
var obj1 = { a : 'a', b : 'b' }; var obj2 = { x : { xxx : 'xxx', yyy : 'yyy' }, y : 'y' }; $.extend(true, obj1, obj2); alert(obj1.x.xxx); // 得到"xxx" obj2.x.xxx = 'zzz'; //修改obj2对象属性的内联值,不影响合并后对象obj1 alert(obj2.x.xxx); // 得到"zzz" alert(obj1.x.xxx); // 得到"xxx" //值保持;如果不加true,则得到“zzz”
(3)jQuery.fn.extend(object);
jQuery.fn = jQuery.prototype 即指向jQuery对象的原型链,对其它进行的扩展,作用在jQuery对象上面;一般用此方法来扩展jQuery的对象插件
//将hello方法合并到jquery的实例对象中。 $.fn.extend({ hello:function(){alert('hello');} }); //在jquery全局对象中扩展一个net命名空间。 $.extend($.net,{ hello:function(){alert('hello');} }); //使用jQuery.net.hello();
浅复制的实现
$ = { extend : function(target, options) { for (name in options) { target[name] = options[name]; } return target; } };
深复制的实现
$ = { extend : function(deep, target, options) { for (name in options) { copy = options[name]; if (deep && copy instanceof Array) { target[name] = $.extend(deep, [], copy); } else if (deep && copy instanceof Object) { target[name] = $.extend(deep, {}, copy); } else { target[name] = options[name]; } } return target; } };
四、jQuery.clone
$(selector).clone(includeEvents) //includeEvents:可选。布尔值。规定是否复制元素的所有事件处理。默认地,副本中不包含事件处理器。
五、jQuery.map
$(':checkbox').map(function() { return this.id; }).get().join(',');
由于返回值是 jQuery 封装的数组,使用 get() 来处理返回的对象以得到基础的数组。两种转换方式将一个jQuery对象转换成DOM对象:[index]和.get(index);
var arr1= [0,1,2]; var arr2=$.map( arr1, function(n){ return n; }); console.log(arr1==arr2)//false
jQuery.map源码,return数组数据
function (elems, callback, arg) { var value, key, ret = [], i = 0, length = elems.length, // jquery objects are treated as arrays isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ((length > 0 && elems[0] && elems[length - 1]) || length === 0 || jQuery.isArray(elems)); // Go through the array, translating each of the items to their if (isArray) { for (; i < length; i++) { value = callback(elems[i], i, arg); if (value != null) { ret[ret.length] = value; } } // Go through every key on the object, } else { for (key in elems) { value = callback(elems[key], key, arg); if (value != null) { ret[ret.length] = value; } } } // Flatten any nested arrays return ret.concat.apply([], ret); }