深浅拷贝你了解多少

63 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第21天,点击查看活动详情

深浅拷贝

三个词(描述对象和对象之间的关系)

        1. 赋值

            把一个对象的地址赋值给另一个变量

            两个变量操作同一个空间

 // 1. 赋值     
 var o1 = {     
 name: 'Jason' 
 } 
 var o2 = o1

        2. 浅拷贝

            把对象里面的每一个成员, 复制一份一模一样的内容

            放到另一个对象里面

            当某一个对象成员是复杂数据类型的时候

            这个成员依旧是一样的

            只是操作对象里面一层可以没有关系, 如果再深层次就会出现问题

 2. 浅拷贝   
 var o1 = {     
 name: 'Jack',    
 age: 18,      
 info: {      
 class: 'gp20',      
 score: 100      
 }     }    
 var o2 = {}  
 for (var key in o1) {   
 o2[key] = o1[key]   
 }   
 o2.name = 'Rose' 
 o2.info.score = '90'   
 console.log(o1, o2)

          3. 深拷贝

            对象空间里面不管多少层, 都是相对独立

      for in 遍历赋值

          只 要碰到某一个是复杂数据类型 对象 或者 数组

            再次进入到这个数据类型里面进行二次遍历

            方案 1: 利用递归思想实现深拷贝

              第一遍遍历放在一个函数里面

          如果遍历的时候, 发现有一个数据是 数组 或者 对象

              则重新调用函数

方案 2: json

            不管多复杂的数据类型, 转换成 json 以后就是字符串

              字符串的赋值时基本数据类型

              赋值以后再转换回来

 // 3. 深拷贝   
 var o1 = {   
 name: 'Jack',  
 age: 18,    
 info: {       
 class: 'gp20',    
 scroe: 100,      
 time: {        
 createTime: 100,         
 updateTime: 200,      
 times: [1, 2, 3, 4, 5]   
 }     
 } 
 } 
 var o2 = {}
 // 第一遍遍历     
 for (var key in o1) { 
 if (typeof o1[key] === 'object') { 
 if (o1[key].constructor === Array) {  
 o2[key] = []        
 } else {  
 o2[key] = {}     
 }      
 for (var key2 in o1[key]) {  
 o2[key][key2] = o1[key][key2]    
 }      } else {      
 o2[key] = o1[key]      }   
 }     
 function deep(o2, o1) {   
 for (var key in o1) {      
 if (o1[key].constructor === Array) {  
 o2[key] = []        
 deep(o2[key], o1[key]) 
 } else if (o1[key].constructor === Object) { 
 o2[key] = {}        
 deep(o2[key], o1[key])   
 } else {         
 o2[key] = o1[key]   
 }    
 } 
 } 
 deep(o2, o1)
 // o2 = JSON.parse(JSON.stringify(o1)) 
 o2.name = 'Rose'  
 o2.info.scroe = 90  
 o2.info.time.createTime = 300  
 o2.info.time.times[100] = 99   
 console.log(o1, o2)

           

jQuery 里面的深浅拷贝

        jQuery 里面提供了一个进行深浅拷贝的方法

        $.extend()

          1. $.extend(对象 1, 对象 2, 对象 3, ...)

            浅拷贝是从第二个参数开始的每一个对象的数据拷贝到第一个对象中

          2. $.extend(true, 对象 1, 对象 2, 对象 3, ...)

            深拷贝是从第三个参数开始的每一个对象的数据拷贝到第二个对象中

        这里特别注意一下:

          在进行拷贝时, 不管是深拷贝还是浅拷贝

          至少传递两个参数

          传递一个参数的时候, 不是进行拷贝

   var o1 = {     
   name: '我是 o1'  
   }  
   var o2 = {   
   age: 18,     
   info: {       
   class: 'gp20'  
   }    
   }   
   var o3 = {   
   gender: '男',  
   list: [1, 2, 3, 4, 5]   
   }
   // 进行深拷贝  
   $.extend(true, o1, o2)  
   o1.age = 20   
   o1.info.class = '你好' 
   console.log(o1, o2)

 jQuery 的插件扩展

        jQuery 再设计的时候, 封装了好多的方法

        可以向 jQuery 里面扩展一些内容

        插件扩展机制提供了两个方法

 1. 扩展到 jQuery 本身, 作为全局方法调用

        使用方法: $.extend({ 你扩展的方法 })

        $.extend({ a: function () {} })

          相当于扩展了一个 a 方法再 jQuery 本身

          如果你向调用, 就书写 $.a()

// 向 jQuery 身上扩展了一个 a 方法  
$.extend({       getCookie (val) {  
const cookie = document.cookie      
var o = ''        
if (val) {        
cookie.split('; ').forEach(item => {  
var t = item.split('=')           
if (t[0] === val) {         
o = t[1]            
}          
})          
} else {   
o = {}       
cookie.split('; ').forEach(item => {    
const t = item.split('=')          
o[t[0]] = t[1]          
})        }       
return o         },  
setCookie () {      }     })  
const res = $.getCookie('a')  
console.log(res)    
console.log($.getCookie())

2. 扩展到 jQuery 的原型上, 就是给 jQuery 的元素集合使用

        使用方法: $.fn.extend({ 你扩展的方法 })

        $.fn.extend({ a: function () {} })

          等于扩展了一个 a 方法给 jQuery 的元素集合

          如果你想调用, 就书写 $(选择器).a()

        另一种书写的语法

          .extend(.extend(.fn, { 你扩展的方法 })

// 向 jQuery 的原型上扩展方法  
$.fn.extend({      
a: function () {    
console.log('我调用了')     
}   
})   
$.extend($.fn, { 
b () {        
console.log('我是 扩展的 b 方法')     
}   
}
)
// 使用的时候   
$('html').a()    $('html').b()