欧锦赛买球官网-前端百题斩之赋值、浅拷贝、深拷贝大PK
你的位置:欧锦赛买球官网 > 欧锦赛买球官网 > 前端百题斩之赋值、浅拷贝、深拷贝大PK
前端百题斩之赋值、浅拷贝、深拷贝大PK
时间:2021-06-29 19:37 点击:77 次

 

相信老铁们不管是在学习还是面试过程中,都会遇到赋值、浅拷贝、深拷贝,特别是浅拷贝和深拷贝,我记忆比较深刻的遇到这个问题有两次:

一次系统写出bug就是因为对深浅拷贝理解不清楚; 百度面试。 23.1 赋值

赋值指的就是将一个变量直接赋值给另一个变量,如下所示:

const a1 = 10; const a2 = a1; console.log(a2); // 10  const b1 = {     m: 10,     n: 20 };  const b2 = b1; console.log(b2); // { m: 10, n: 20 } 

如上所示,赋值就是将一个值赋给另一个值,在赋值过程中要注意两点:

对于基本类型赋值就是在栈内存中开辟一个新的存储区域来存储新的变量;

对于引用类型赋值,就是将该引用类型的地址,该地址指向堆中的同一值。

23.2 浅拷贝

23.2.1 基本实现

浅拷贝指的就是循环遍历对象一遍,将该对象上的属性赋值到另一个对象上。在这个过程中属性值为基本类型则拷贝的就是基本类型的值;若该值为引用类型,则拷贝的就是就是一个内存地址。

function clone(source) {     if (!(typeof source === 'object' && source !== null)) {         return source;     }     const target = {}; // 只考虑Object类型     for (let [key, value] of Object.entries(source)) {         target[key] = value;     }      return target; }  const obj = {     a: 10,     b: {         m: 20     } };  const cloneObj = clone(obj);  cloneObj.a = 20; cloneObj.b.m = 30;  console.log(obj); // { a: 10, b: { m: 30 } } console.log(cloneObj); // { a: 20, b: { m: 30 } } 

上述就是简单的浅拷贝过程,可以看到浅拷贝就是将原始对象中的值遍历一层,然后赋值给一个新的对象。在遍历过程中可以获取到一下信息:

遍历到a属性的时候,其是一个基本类型,所以会在栈内存中创建一个新的存储区域来存储变量。

遍历到b属性的时候,由于其为引用类型,其会在栈内存中存储器堆地址,从而指向堆内存中的同一对象。

当通过浅拷贝创建的对象cloneObj中的a属性和b.m属性重新赋值,可以发现a属性值不一样,但b.m属性值却发生了变化,从而验证了上述1、2两条分析。

23.2.2 进阶

既然本章我们讲了浅拷贝,那么不得不了解Object.assign(),该方法就是一个浅拷贝的过程,用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target)。

23.2.2.1 基础

要实现一个函数首先应该了解一个函数,对于该方法的基本使用就不再赘述,下面主要讲几个注意点:

如果目标对象与源对象有同名属性(或多个源对象有同名属性),则后面的属性会覆盖前面的属性; 如果只有一个参数,Object.assign会直接返回该参数。如果该参数不是对象,则会先转为对象,然后再返回;(注意:由于undefined和null无法转为对象,将它们作为参数会报错) 非对象参数出现在源对象位置,这些参数会转化为对象,如果无法转成对象便跳过(所以undefined和null不会报错)。(注意:字符串会以数组形式复制到目标对象,其它不会) 只复制源对象的自身属性(不复制继承属性),也不复制不可枚举的属性; 属性名为Symbol值的属性也会被Object.assign复制。

23.2.2.2 实现

上面阐述了主要的注意点,下面我们就来实现一下Object.assign(),实现步骤如下所示:

对目标对象进行判断,不能为null和undefined; 将目标转换为对象(防止string、number等); 获取后续源对象自身中的可枚举对象(包含Symbol)复制到目标对象; 返回该处理好的目标对象; 利用Object.defineProperty()将该函数配置为不可枚举的挂载到Object上。
function ObjectAssign(target, ...sources) {     // 对第一个参数进行判断,不能为undefined和null     if (target === undefined 
           
当前网址:http://callopsie.com/oujinsaimaiqiuguanwang/8221.html
tag:前端,百题,斩之,赋值,、,浅,拷贝,深,大,相信,
相关新闻