快捷搜索:  汽车  科技

前端开发代码复制粘贴多吗(前端面试之赋值)

前端开发代码复制粘贴多吗(前端面试之赋值)let a = { name: 'xl' age: 20 children: ['1' '2' '3'] } let b = {} for(let props in a) { if (a.hasOwnProperty(props)) { b[props] = a[props] } } console.log('a:' a) console.log('b:' b) a.name = 'xw' a.children[1] = '4' console.log('a:' a) console.log('b:' b) 输出结果如下:首先看代码如下:首先看如下代码:le

在平时的面试过程中,赋值、浅拷贝和深拷贝是被经常问到的,面试官可能会问他们的区别,也可能会让你手写一个深拷贝或者浅拷贝函数。要能够完美的回答这一系列问题,就应该对他们了解透彻,掌握他们的底层区别。

数据分为基本数据类型(String Number Boolean Null Undefined,Symbol)和对象数据类型。

前端开发代码复制粘贴多吗(前端面试之赋值)(1)

堆和栈堆关系

  • 基本数据类型的特点:直接存储在栈(stack)中的数据
  • 引用数据类型的特点:存储的是该对象在栈中引用,真实的数据存放在堆内存里

引用数据类型在栈中存储了指针,该指针指向堆中该实体的起始地址。当解释器寻找引用值时,会首先检索其在栈中的地址,取得地址后从堆中获得实体。

一、赋值

首先看如下代码:

let a = { name: 'xl' age: 20 } let b = a console.log('a:' a) console.log('b:' b) a.name = 'xw' console.log('a:' a) console.log('b:' b)

输出的结果:

a: { name: 'xl' age: 20 } b: { name: 'xl' age: 20 } a: { name: 'xw' age: 20 } b: { name: 'xw' age: 20 }

发现当把a对象赋值给了b,然后修改a对象里面的name值,b对象里面的name值也跟着变化了,说明这两个对象是同一个对象,与其说这两个变量其实使用的是同一个对象,不如说这两个对象所指向的内存地址是同一个,也就是他们的栈地址是同一个。

浅拷贝

首先看代码如下:

let a = { name: 'xl' age: 20 children: ['1' '2' '3'] } let b = {} for(let props in a) { if (a.hasOwnProperty(props)) { b[props] = a[props] } } console.log('a:' a) console.log('b:' b) a.name = 'xw' a.children[1] = '4' console.log('a:' a) console.log('b:' b)

输出结果如下:

a: { name: 'xl' age: 20 children: [ '1' '2' '3' ] } b: { name: 'xl' age: 20 children: [ '1' '2' '3' ] } a: { name: 'xw' age: 20 children: [ '1' '4' '3' ] } b: { name: 'xl' age: 20 children: [ '1' '4' '3' ] }

输出结果表示,修改a对象的name属性的值,b对象不会变化,修改a对象的children数组对象里面的值,b对象也随之改变。

该结果的实质就是浅拷贝会拷贝栈里面的数据,而不会拷贝堆里面的数据,因此a b两个对象里面的children数组是堆里面的同一个,所以修改其中一个,另外一个也会改变。

浅拷贝的实现方式:

  1. Object.assign()
  2. Array.prototype.concat()
  3. Array.prototype.slice()
深拷贝

首先代码如下:

let a={ name: 'xl' age: 20 children: ['1' '2' '3'] } function deepClone(obj){ let objClone = Array.isArray(obj)?[]:{}; if(obj && typeof obj==="object"){ for(key in obj){ if(obj.hasOwnProperty(key)){ //判断obj子元素是否为对象,如果是,递归复制 if(obj[key]&&typeof obj[key] ==="object"){ objClone[key] = deepClone(obj[key]); }else{ //如果不是,简单复制 objClone[key] = obj[key]; } } } } return objClone; } let b = deepClone(a); console.log('a:' a) console.log('b:' b) a.name = 'xw' a.children[0]=2; console.log('a:' a) console.log('b:' b)

输出结果如下:

a: { name: 'xl' age: 20 children: [ '1' '2' '3' ] } b: { name: 'xl' age: 20 children: [ '1' '2' '3' ] } a: { name: 'xw' age: 20 children: [ 2 '2' '3' ] } b: { name: 'xl' age: 20 children: [ '1' '2' '3' ] }

如上所示,不管修改a对象里面的哪个属性,b对象丝毫不受影响。主要的原因就是使用递归方法实现深度克隆:遍历对象、数组直到里边都是基本数据类型,然后再去复制,就是深度拷贝。深拷贝不仅会拷贝栈的数据,也会在堆里面另外开出一个内存存放引用型数据。

深拷贝的实现方式:

  1. JSON.parse(JSON.stringify())
  2. 函数库lodash的cloneDeep()方法

猜您喜欢: