当前位置:首页 » 《关注互联网》 » 正文

【深入探讨】JavaScript 中的 forEach 和 map 区别

0 人参与  2024年05月03日 11:27  分类 : 《关注互联网》  评论

点击全文阅读


? 个人主页:不叫猫先生,公众号:前端Clodplay
?‍♂️ 作者简介:前端领域优质作者、阿里云专家博主,共同学习共同进步,一起加油呀!
✨优质专栏:VS Code插件开发极速入门
? 资料领取:前端进阶资料可以找我免费领取

目录

区别手写 map 和 forEachmap 和 forEach 会不会改变原数组处理基本类型数据处理引用类型数据 思考:为什么基础数据类型不会更改原数据,引用类型不会好书推荐

在这里插入图片描述

区别

map会返回一个新的数组,而forEach不会。具体探讨一下,实则会有新的发现!

下面来探讨一下原因

手写 map 和 forEach

手写map,如下:

function myMap(array, callback) {  //存储结果  const result = [];  for (let i = 0; i < array.length; i++) {    result.push(callback(array[i], i, array));  }  return result;}

调用上面的myMap函数

// 定义一个回调函数,用于对数组元素进行操作function double(value) {  return value * 2;}// 定义一个数组const numbers = [1, 2, 3, 4, 5];// 调用 myMap 函数,并传入定义好的回调函数const doubledNumbers = myMap(numbers, double);console.log(doubledNumbers); // 输出 [2, 4, 6, 8, 10]

手写forEach,如下:

function myForEach(array, callback) {  for (let i = 0; i < array.length; i++) {    callback(array[i], i, array);  }}

调用上面的myForEach函数

// 定义一个回调函数,用于对数组元素进行操作function logItem(item, index) {  console.log(`Index ${index}: ${item}`);}// 定义一个数组const fruits = ["Apple", "Banana", "Orange", "Mango"];// 调用 myForEach 函数,并传入定义好的回调函数myForEach(fruits, logItem);

总结:
上面可以看到 forEach 和 map 的实现原理相似。它们都是通过遍历数组,对数组的每个元素执行特定的函数。区别主要在于它们处理函数返回值的方式不同
forEach 忽略函数的返回值,而 map 则将函数的返回值收集到一个新的数组中

可以看到 map 和 forEach都会有一个for循环处理,且map有return

 for (let i = 0; i < array.length; i++) {    result.push(callback(array[i], i, array));  }for (let i = 0; i < array.length; i++) {    callback(array[i], i, array);  }

那么能不能forEach也return,测试一下

        const array = [1, 2, 3]        const result = array.forEach((element) => {            return element * 2; // 这个返回值不会被 forEach 捕获或使用        });        console.log(result); // 输出: undefined

但是map,return 之后是有值的

        const array = [1, 2, 3]        const result = array.map((element) => {            return element * 2; // 这个返回值会被 map 捕获或使用        });        console.log(result); // 输出: [2, 4, 6]

map 和 forEach 会不会改变原数组

map 和 forEach 会不会改变原数组,需要看数据类型,具体分为基础数据类型和引用类型。

处理基本类型数据

forEach 处理基本数据类型

        let array = [1, 2, 3, 4];        array.forEach(item => {            item = item + 1        })        console.log(array); // [1,2,3,4]

map 处理基本数据类型

        let array = [1, 2, 3, 4];        array.map(item => {            item = item + 1        })        console.log(array); // [1,2,3,4]

测试后发现,都没有改变原数组

处理引用类型数据

forEach 处理引用类型数据

        const arr = [{            name: 'shaka',            age: 23        }, {            name: 'virgo',            age: 18        }]        arr.forEach(item => {            if (item.name === 'shaka') {                item.age = 100            }        })        console.log(arr); //[{name: 'shaka', age: 100}, {name: 'virgo', age: 18}]

在这里插入图片描述
map 处理引用类型数据

 const arr = [{            name: 'shaka',            age: 23        }, {            name: 'virgo',            age: 18        }]        arr.map(item => {            if (item.name === 'shaka') {                item.age = 100            }        })        console.log(arr); //[{name: 'shaka', age: 100}, {name: 'virgo', age: 18}]

在这里插入图片描述
发现都改变了原数据

思考:为什么基础数据类型不会更改原数据,引用类型不会

这是因为在使用 forEach 和 map 方法时,对引用类型元素的修改会直接反映在原始数组中。这是因为引用类型的元素实际上存储的是引用(内存地址),而非值本身。因此,通过引用可以访问和修改原始数组中的元素。而number、string、Boolean、null、undefined它们在栈内存中直接存储变量与值。

具体解释如下:
基本数据类型为值传递,callback的执行和原数组毫不相干,所以forEach无法修改基本数据的数组
基本数据类型(Primitive data types)如数值(Number)、字符串(String)、布尔值(Boolean)、null 和 undefined 等,它们在内存中是直接存储变量的值,而不是引用。因此,对于基本数据类型,当它们作为数组的元素被传递给 forEach 或 map 方法时,处理的是它们的值的拷贝,而不是原始值本身。因此,对于基本数据类型,任何更改都只是在处理的拷贝上进行,不会影响到原始数组中的值。


引用类型(Reference types)如对象(Object)、数组(Array)和函数(Function)等,它们在内存中存储的是地址,即指向存储实际数据的内存地址。因此,当引用类型的元素被传递给 forEach 或 map 方法时,处理的是对该地址的引用,而不是原始数据本身。这意味着对引用类型的元素进行的任何更改都会直接反映在原始数组中,因为它们都指向相同的内存地址。

好书推荐

《ReactJS入门实践》
在这里插入图片描述
本书涵盖了编写高质量React代码要掌握的一切内容。你将学习使用函数方法和类方法编写React组件;学习如何使用几种不同的方法来管理应用程序的状态,包括使用React Hooks和setState方法;学习如何将组件合在一起来创建完整的动态用户界面;还将学习如何从外部数据源获取数据并在应用程序中使用。此外,本书介绍了如何在用户的Web浏览器中存储数据,以提高应用程序的性能和可用性。谈到可用性,你将会了解在移动设备和桌面上运行应用程序的最佳实践,还将了解如何确保应用程序可访问。

如果你对《ReactJS实践入门》感兴趣的话,可以点击链接购买:链接直达


点击全文阅读


本文链接:http://zhangshiyu.com/post/103097.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1