javascript中对于Object和Array这两个类型,把一个变量赋值给另外一个变量;浅拷贝只是对拷贝对象的引用,深拷贝是完全拷贝,生成一个新的属性相同的对象javascript
浅拷贝只是对拷贝对的引用,二者相互影响 java
例子:obj2拷贝了obj1,obj2改变,obj1也会改变,改变以后2者仍是相同的数组
var obj1 = {a: 1} var obj2 = obj1 obj2.b = 2 console.log(obj1) // {a: 1, b: 2} console.log(obj2) //{a: 1, b: 2} console.log(obj1 == obj2) // true
例子:当第一个传参是你须要拷贝的对象(PS:Object.assign()也能够实现深拷贝)oop
var obj1 = {a: 1} var obj2 = Object.assign(obj1) obj2.b = 2 console.log(obj1) // {a: 1, b: 2} console.log(obj2) // {a: 1, b: 2} console.log(obj1 == obj2) // true
完全拷贝,生成一个新的属性相同的对象 this
例子:拷贝对象不是第一个传参code
var obj1 = {a: 1} var obj2 = Object.assign({}, obj1) obj2.b = 2 console.log(obj1) // {a: 1} console.log(obj2) // {a: 1, b: 2} console.log(obj1 == obj2) // false
var arr1 = [1, [2]] var arr2 = arr1.slice() arr2[1].push(3) arr2.push(4) console.log(arr1) // [1, [2, 3]] console.log(arr2) // [1, [2, 3], 4] console.log(arr1 == arr2) // false
var obj1 = {a: 1} var obj2 = JSON.parse(JSON.stringify(obj1)) console.log(obj1 == obj2) // false obj2.b = 2 console.log(obj1) // {a: 1} console.log(obj2) // {a: 1, b: 2}
var deepCopy = function(obj) { if (typeof obj !== 'object') return; var newObj = obj instanceof Array ? [] : {}; for (var key in obj) { if (obj.hasOwnProperty(key)) { newObj[key] = typeof obj[key] === 'object' ? deepCopy(obj[key]) : obj[key]; } } return newObj; } var obj1 = {a: 1} var obj2 = deepCopy(obj1) console.log(obj1 == obj2) // false obj2.b = 2 console.log(obj1) // {a: 1} console.log(obj2) // {a: 1, b: 2}
var deepCopy = function(obj) { if (typeof obj !== 'object') return; var newObj = obj instanceof Array ? [] : {}; for (var key in obj) { if (obj.hasOwnProperty(key)) { newObj[key] = typeof obj[key] === 'object' ? Object.create(obj[key]) : obj[key]; } } return newObj; } var obj1 = {a: 1} var obj2 = deepCopy(obj1) console.log(obj1 == obj2) // false obj2.b = 2 console.log(obj1) // {a: 1} console.log(obj2) // {a: 1, b: 2}
var obj1 = {a: 1} var obj2 = $.extend(true, {}, obj1) console.log(obj1 == obj2) // false obj2.b = 2 console.log(obj1) // {a: 1} console.log(obj2) // {a: 1, b: 2}
jQuery.extend()源码 对象
jQuery.extend = jQuery.fn.extend = function() { var src, copyIsArray, copy, name, options, clone, target = arguments[0] || {}, // 默认取第一个参数赋值给target i = 1, length = arguments.length, // 获取参数的个数 deep = false; // 默认浅拷贝 // Handle a deep copy situation if ( typeof target === "boolean" ) { // 若是第一个参数类型为boolean,那么把该参数赋值给局部变量deep deep = target; target = arguments[1] || {}; // 把第二个参数赋值给target // skip the boolean and the target i = 2; } // Handle case when target is a string or something (possible in deep copy) if ( typeof target !== "object" && !jQuery.isFunction(target) ) { // target不是object类型或者不是function,就赋值{} target = {}; } // extend jQuery itself if only one argument is passed if ( length === i ) { // 若是只有一个参数,这时候i就是1,length也就是1,那么把target设置为调用者,也就是jQuery对象自己!同时把i递减为0 target = this; // this就是jQuery --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 // deep是否深拷贝,copy是参数属性值 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 ) { // 浅拷贝,且属性值不为undefined target[ name ] = copy; } } } } // Return the modified object return target; };