进阶4: 引用类型对象拷贝

1. 引用类型有哪些?非引用类型有哪些

  • 非引用类型值:
    • 数值、布尔值、字符串、null和undefined,还有深拷贝
  • 引用类型:
    • 对象、数组、函数、正则

2. 如下代码输出什么?为什么

var obj1 = {a:1, b:2};
var obj2 = {a:1, b:2};
console.log(obj1 == obj2); //输出 false 因为 obj1和obj2指向不同的堆内存
console.log(obj1 = obj2); //输出 {a:1, b:2}  因为obj2赋值给obj1,实质上就是令obj1也去指向obj2的堆内存
console.log(obj1 == obj2); //输出 ture 因为经过了上面的操作,obj1已经和obj2指向同一个堆内存,并且是严格相等 ===

3.如下代码输出什么? 为什么

var a = 1
var b = 2
var c = { name: '饥人谷', age: 2 }
var d = [a, b, c] //数组内可以含有对象

var aa = a //基本类型 aa = 1
var bb = b //基本类型 bb = 2
var cc = c  //引用类型,令cc指向和c相同的堆内存地址
var dd = d  //引用类型,令dd指向和d相同的堆内存地址

a = 11 //aa不受影响,依然为1
b = 22 //bb不受影响,依然为2
c.name = 'hello' //cc.name也变成 'hello'
d[2]['age'] = 3 //dd变成[1, 2, { name: 'hello', age: 3 '}]   a 和 b 没变是因为其是基本类型,
//在最开始声明数组 d 的时候,a 和 b 就已经在数组的内存堆中被重新创建了,而不是引用自外部

console.log(aa) //输出 1
console.log(bb) //输出 2
console.log(cc)// 输出 { name: 'hello', age: 3 }
console.log(dd)// 输出 [1, 2, { name: 'hello', age: 3 '}]

4.如下代码输出什么? 为什么

var a = 1
var c = { name: 'jirengu', age: 2 }

function f1(n){
  ++n
}
function f2(obj){
  ++obj.age
}

f1(a) //a是非引用类型,按值传递,传入f1后,相当于在 f1 的作用域内 有 var n = a,此时 n 开辟了新的内存用来存放 1,不影响a
f2(c) //c是引用类型,按引用传递,传入f2后,相当于 var obj = c,这里obj虽然也开辟了新的内存,但仅仅是用来存放和c同样的内存地址,
//存的是一个地址坐标,obj 和 c 共同指向相同的堆内存,操作的时候是操作的堆内存,所以改变了 c.age
f1(c.age) //c.age 作为参数传入 f1 的时候,实质就已经是 number 了,n 开辟了新的内存
console.log(a) //所以输出 1
console.log(c) //所以输出 { name: 'jirengu', age: 3 }

5.过滤如下数组,只保留正数,直接在原数组上操作

var arr = [3,1,0,-1,-3,2,-5]
function filter(arr){
  for(var i = 0; i < arr.length; i++){
    if(arr[i] <= 0){
      arr.splice(i,1)   // i 代表位于 index i 的元素,1代表删除从index i 开始的一个元素,也就是 index i 这个元素
      filter(arr)
    }
  }
}
filter(arr)
console.log(arr) // [3,1,2]

6.过滤如下数组,只保留正数,原数组不变,生成新数组

var arr = [3, 1, 0, -1, -3, 2, -5];
var arr2 = [];
function filter(arr) {
  for (var i = 0; i < arr.length; i++) {
    if (arr[i] > 0) {
      arr2.push(arr[i]); // push方法,可以向 arr2 数组的末尾添加一个或多个元素,并返回新的长度
    }
  }
}
filter(arr);
console.log(arr2) // [3,1,2]
console.log(arr)  // [3,1,0,-1,-2,2,-5]

7.写一个深拷贝函数,用两种方式实现

第一种:

// 使用递归
var obj1 = {
  age: 20,
  name: 'wangpeng',
  friend : {
    name: 'ruoyu',
    sex: 'male'
  }
}

function copy(obj){
  var newObj = {}
  for(key in obj){
    if(obj.hasOwnProperty([key])){
      if(typeof obj[key] === 'number' || typeof obj[key] === 'string' || typeof obj[key] === 'boolean' || 
         obj[key] === undefined || obj[key] === null ){
        newObj[key] = obj[key]    
      }else{
        newObj[key] = copy(obj[key])
      }
    }
  }
  return newObj
}

var obj2 = copy(obj1)
console.log(obj2)

第二种:

// 使用JOSN 进行深拷贝
var obj1 = {
  age: 20,
  name: 'wangpeng',
  friend : {
    name: 'ruoyu',
    sex: 'male'
  }
}

function copy(obj) {
var newObj = {}
newObj = JSON.parse( JSON.stringify(obj) )
return newObj
}

var obj2 = copy(obj1)
console.log(obj2)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1.javascript引用类型有哪些?非引用类型有哪些? 引用类型:对象、数组、函数、正则表达式,指保存在堆内存...
    FLYSASA阅读 228评论 0 0
  • 1.引用类型有哪些?非引用类型有哪些 基本类型(数值、布尔值、null、undefined):指的是保存在栈内存中...
    我七阅读 168评论 0 0
  • 1. 引用类型有哪些?非引用类型有哪些? 引用类型值(对象、数组、函数、正则):指的是那些保存在堆内存中的对象,变...
    饥人谷_哈噜噜阅读 275评论 0 0
  • 1.引用类型有哪些?非引用类型有哪些 引用类型包括:数组、对象、正则、函数 非引用类型(即基本类型):数值、布尔值...
    饥人谷_js_chen阅读 284评论 0 0
  • 庭前花落泪 楼外镜湖心 江湖无情剑 红叶有诗怜
    星尘梦羽阅读 148评论 2 4