0
点赞
收藏
分享

微信扫一扫

深入理解关于forEach、map等循环方法无法修改当前遍历值

拾杨梅记 2022-01-25 阅读 94

深入理解关于forEach、map等循环方法无法修改当前遍历值

在这里插入图片描述

前言

在对一些数组进行遍历、处理时,JS自带的遍历方法有很多种,往往不加留意,就可能导致知识混乱的现象,并且其中还存在一些坑。

实验

示例一

let arrList = [
  1,
  '1',
  { a: 1, b: '1' },
  [1, '1'],
  undefined,
  null
]

arrList.forEach(item => {
  item = 2
})


// arrList.map(item => {
//   item = 2
// })


console.log(arrList) //[1,'1',{ a: 1, b: '1' },[1, '1'],undefined,null]

可以发现,当前数组并没有发生改变

示例二

let arrList = [
  1,
  '1',
  { a: 1, b: '1' },
  [1, '1'],
  undefined,
  null
]

arrList.forEach(item => {
    if(Object.prototype.toString.call(item) === '[object Object]'){
        item.a = 2
        item.b = '2'
    }
     if(Object.prototype.toString.call(item) === '[object Array]'){
       item[0] = 2
       item[1] = '2'
    }
   
})



console.log(arrList) //[1,'1',{ a: 2, b: '2' },[2, '2'],undefined,null]

在这里我们把对象 {a:1,b:‘1’} 改变了 { a: 2, b: ‘2’ },数组[1,‘1’]也变成了[2,‘2’]

那这是为什么呢?

数据类型

这我们就要先搞懂数据类型了
最新的 ECMAScript 标准定义了 8 种数据类型:
7 种原始类型,使用 typeof 运算符检查:

  • undefined:typeof instance === “undefined”
  • Boolean:typeof instance === “boolean”
  • Number:typeof instance === “number”
  • String:typeof instance === "string
  • BigInt:typeof instance === “bigint”
  • Symbol :typeof instance === “symbol”
  • null:typeof instance === “object”

Object:typeof instance === “object”。任何 constructed 对象实例的特殊非数据结构类型,也用做数据结构:new Object,new Array,new Map,new Set,new WeakMap,new WeakSet,new Date,和几乎所有通过 new keyword 创建的东西。

又分为两大类型

  • 基本类型: null,undefined,boolean,number,string,symbol
  • 引用类型:Object: Array ,Function, Date, RegExp等

image.png

基本类型和引用类型

  • 基本数据类型:基本类型值在内存中占据固定大小,直接存储在栈内存中的数据
  • 引用数据类型:引用类型在栈中存储了指针,这个指针指向堆内存中的地址,真实的数据存放在堆内存里。

image.png

也就是说,基本类型的值是直接访问的,而引用类型的值是存在堆内存中,通过栈内存中的地址指向堆内存中的真实数据进行访问的

结论

这里大概也能猜到在执行forEach遍历方法的时候做了些什么事情了。

也就是说,当前遍历的数组不是原数组
所以当直接item = 2这样直接赋值修改的时候是没有修改原数组的,只是修改了当前遍历的数组。

而为什么 item.b = '2'就可以修改里面的值呢?

通过先前理解的基本类型和引用类型可以理解

当遍历到当前数组里面的对象的时候 当前item拿到是当前对象的堆内存的地址,而不是真实的栈内存的真实数据,所以当前操作的是通过该地址指向当前引用类型的真实数据

而当前遍历数组和原数组是共同同一个地址指向,所以就能理解为什么修改当前遍历数组的对象,原数组也会改变了。

举报

相关推荐

0 条评论