谁动了我的数据

在工作中,我都没去改变它,它的值却变了。其实这个问题的原因很简单,就是这个数据是个引用类型而已。

什么是引用类型

在JavaScript中的数据有两种类型,一种是基本类型,一种是引用类型。基本类型的数据是存放在栈内存中的,而引用类型的数据是存放在堆内存中的。

我们把一个引用类型的数据Object赋值给变量obj1时,变量obj1存放在栈内存中,数据Object存放在堆内存中。我们通过访问变量obj1时,栈内存中的变量obj1会去引用(访问)堆内存中的数据Object,故将数据Object称为引用类型的数据。

如果把变量obj1在赋值给变量obj2,变量obj2会添加到栈内存中,当我们访问变量obj2时,栈内存中的变量obj2还是会去访问堆内存中的数据Object

 

 如果给变量obj2添加了name属性,会改变堆内存中的数据Object,此时再访问变量obj1就会发现多了个name

在实际业务中,如果不小心把一个被引用类型的数据赋值的变量,再赋值给另外一个变量,改变这个变量,就会产生本文开头所描述的现象--谁动了我的数据。

原生的引用类型

在JavaScript中原生的引用类型有这几种:Object、Array、RegExp、Date、Function、特殊的基本包装类型(String、Number、Boolean)以及单体内置对象(Global、Math)。而最常用的只有对象(Object)、数组(Array)两种。

如何避免数据被莫名地改变 

避免数据被莫名地改变,很简单,遇到引用类型数据赋值给变量前,先把数据进行处理,返回一个新数据后在赋值。处理的目的就是返回一个新数据,有以下几种方法: 

  • 克隆

    对对象或数组进行克隆都能返回一个新数据。

  • JSON.stringify()JSON.parse()

    先用JSON.stringify()把对象或数组转成一个JSON字符串,在用JSON.parse()将其解析,会返回一个新的对象或数组。

  • slice

const arr = [1,2];
const arr1 = arr.slice();

 以上arr1是一个新数组,改变对arr不影响。

map

const arr = [1,2];
const arr1 = arr.map((item) =>{
    return item;
})

以上arr1是一个新数组,改变对arr不影响。

filter

 const arr = [1,2];
 const arr1 = arr.map((item) =>{
     return true;
 })

 以上arr1是一个新数组,改变对arr不影响。

concat

const arr = [1,2];
const arr1 = arr.concat()

 以上arr1是一个新数组,改变对arr不影响。

Object.assign 

const obj = {
  a:1
};
const obj1 = Object.assign(obj);

 以上obj1是一个新对象,改变对obj不影响。

ES6扩展运算符

const arr = [1,2];
const arr1 = [...arr]

 以上arr1是一个新数组,改变对arr不影响。

const obj = {
   a:1
};
const obj1 = {...obj};

 以上obj1是一个新对象,改变对obj不影响。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值