js的原型和原型链,基本数据类型和引用数据类型的区别以及深拷贝和浅拷贝的区别和实现

一、js原型/原型链?

1.原型

概念:
js中每一个构造函数都有一个与之对象的js对象来表示,这个对象中都有prototype属性,这个属性就叫函数的原型。原型就是函数对象的prototype属性。
优点:构造函数的所有实例化对象都可以共享函数原型的属性和方法。
缺点:函数的原型delete方法删除不掉

2.原型链

实例化一个对象,我们要使用对象的属性或者方法,他会先从当前对象进行查找,如果找不到,就去函数的原型中去查找,如果原型中也不存在,就去函数的父对象查找,如果最终没找到,返回undefined。

二、(值类型)基本数据类型和引用数据类型的区别?

值类型

  • 占用空间固定,保存在栈中(当一个方法执行时,每个方法都会建立自己的内存栈,在这个方法内定义的变量会逐个放入这块栈内存里,随着方法的执行结束,这个方法的内存栈也将自然销毁了。因此,所有在方法中定义的变量都是仿制栈内存中的;栈内存储的基础变量以及一些对象的引用变量,基础变量的值是存储在栈中,而引用变量存储在栈中是指向堆中的数组或者对象的地址,这就是为何修改引用类型总会影响到其他指向这个地址的引用变量。)
  • 保存与复制的是值本身
  • 使用typeof检测数据的类型
  • 基本类型数据是值类型

引用类型

  • 占用空间不固定,保存在堆中(当我们在程序中创建一个对象时,这个对象将被保存到运行时数据区中,以便反复利用(因为对象的创建成本通常较大),这个运行时数据区就是堆内存。堆内存中的对象不会随方法的结束而销毁,即使方法结束后,这个对象还可能被另一个引用变量所引用(方法的参数传递时很常见),则这个对象依然不会被销毁,只有当一个对象没有任何引用变量引用它时,系统的垃圾回收机制才会在核实的时候回收它。)
  • 保存与复制的是指向对象的一个指针
  • 使用instanceof检测数据类型
  • 使用new()方法构造出的对象的引用型

三、深拷贝和浅拷贝的区别?如何实现

浅拷贝值复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存。浅拷贝只复制对象的第一层属性。

但深拷贝会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象。对对象的属性进行递归复制。

实现方式

- 浅拷贝

  • 使用Object.assign({},obj)第一个参数是一个空对象,第二个参数是你要复制的对象;通过这个方法我们知道浅拷贝不能修改基础的数据类型,可以修改引用的数据类型;

  • ES6中的…扩展运算符来进行浅拷贝的实现;

  • Object.assign()实现

Object.assign() 方法可以把任意多个的源对象自身的可枚举属性拷贝给目标对象,然后返回目标对象。但是 Object.assign() 进行的是浅拷贝,拷贝的是对象的属性的引用,而不是对象本身。

var obj = { a: {a: "hello", b: 21} };

var initalObj = Object.assign({}, obj);

initalObj.a.a = "changed";

console.log(obj.a.a); //  "changed"

注意:当object只有一层的时候,是深拷贝,例如如下

  var obj1 = { a: 10, b: 20, c: 30 };
  var obj2 = Object.assign({}, obj1);
  obj2.b = 100;
  console.log(obj1);
  // { a: 10, b: 20, c: 30 } <-- 沒被改到
  console.log(obj2);
  // { a: 10, b: 100, c: 30 }
  • 深拷贝

    • 对象只有一层的话可以使用上面的:Object.assign()函数

    • 转成 JSON 再转回来

   var obj1 = { body: { a: 10 } };
    var obj2 = JSON.parse(JSON.stringify(obj1));
    obj2.body.a = 20;
    console.log(obj1);
    // { body: { a: 10 } } <-- 沒被改到
    console.log(obj2);
    // { body: { a: 20 } }
    console.log(obj1 === obj2);
    // false
    console.log(obj1.body === obj2.body);
    // false
用JSON.stringify把对象转成字符串,再用JSON.parse把字符串转成新的对象。
  • 使用Object.create()方法

    直接使用var newObj = Object.create(oldObj),可以达到深拷贝的效果。

function deepClone(initalObj, finalObj) {    
  var obj = finalObj || {};    
  for (var i in initalObj) {        
    var prop = initalObj[i];        // 避免相互引用对象导致死循环,如initalObj.a = initalObj的情况
    if(prop === obj) {            
      continue;
    }        
    if (typeof prop === 'object') {
      obj[i] = (prop.constructor === Array) ? [] : Object.create(prop);
    } else {
      obj[i] = prop;
    }
  }    
  return obj;
}
  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值