• 【面试题】在循环 for、for-in、forEach、for-of 、map中改变item的值,会发生什么?


    听说你精通循环,我不信

    真正开始写业务逻辑,就离不开循环。而循环一直是编程中基础的基础。但是作为一个工作多年的前端程序员,一定还有人不了解循环的基础知识。

    下面我们一起来看看,在循环中如果改变了item的值会发生什么:

    先给大家推荐一个实用面试题库

    1、前端面试题库 (面试必备)            推荐:★★★★★

    地址:前端面试题库

    forEach

    改变item本身

    1. const list = [
    2. {name: 'a', count: 1},
    3. 2,
    4. function fn() {
    5. console.log(3);
    6. },
    7. Symbol(),
    8. 'sss',
    9. [4,4,4,4],
    10. new Date()
    11. ]
    12. list.forEach(item => {
    13. item = 3
    14. })
    15. console.log(list)
    1. [
    2. { name: 'a', count: 1 },
    3. 2,
    4. [Function: fn],
    5. Symbol(),
    6. 'sss',
    7. [ 4, 4, 4, 4 ],
    8. 2022-09-13T10:40:17.322Z
    9. ]

    我们发现,基础类型的几个,string, number,Symbol()的内容都没有发生变化。

    改变item的属性

    1. const list = [
    2. {name: 'a', count: 1},
    3. 2,
    4. function fn() {
    5. console.log(3);
    6. },
    7. Symbol(),
    8. 'sss',
    9. [4,4,4,4],
    10. new Date()
    11. ]
    12. list.forEach(item => {
    13. item.count = 3
    14. })
    15. console.log(list)
    1. [ { name: 'a', count: 3 }, 2, [Function: fn] { count: 3 },
    2. Symbol(),
    3. 'sss',
    4. [ 4, 4, 4, 4, count: 3 ],
    5. 2022-09-13T10:41:26.631Z { count: 3 }
    6. ]

    我们发现:

    • 基础类型的,依旧没有发生改变。

    • 引用类型的变量,如果自身带了count属性,该属性就会被修改;如果不带该属性,就会添加count属性。

    for

    改变item本身

    由于for 循环里,没有专门的一个变量"item",可以获取到对应的引用,我们只能用list[index]的形式去获取到每一项。

    我们运行看看效果。

    1. const list = [
    2. {name: 'a', count: 1},
    3. 2,
    4. function fn() {
    5. console.log(3);
    6. },
    7. [4,4,4,4],
    8. new Date()
    9. ]
    10. for (let i = 0; i < list.length; i ++) {
    11. list[i] = 4
    12. }
    13. console.log(list)
    1. [ 4, 4, 4, 4, 4 ]

    全部被无差别覆盖了。

    改变item的属性

    1. const list = [
    2. {name: 'a', count: 1},
    3. 2,
    4. function fn() {
    5. console.log(3);
    6. },
    7. [4,4,4,4],
    8. new Date()
    9. ]
    10. for (let i = 0; i < list.length; i ++) {
    11. list[i].count = 4
    12. }
    13. console.log(list)
    1. [
    2. { name: 'a', count: 4 },
    3. 2,
    4. [Function: fn] { count: 4 },
    5. [ 4, 4, 4, 4, count: 4 ],
    6. 2022-09-13T10:44:50.164Z { count: 4 }
    7. ]

    我们发现,和forEach的时候,表现一致:

    • 基础类型的,依旧没有发生改变。

    • 引用类型的变量,如果自身带了count属性,该属性就会被修改;如果不带该属性,就会添加count属性。

    for-in

    1. const list = [
    2. {name: 'a', count: 1},
    3. 2,
    4. function fn() {
    5. console.log(3);
    6. },
    7. [4,4,4,4],
    8. new Date()
    9. ]
    10. for(let i in list) {
    11. list[i] = 4
    12. }
    13. console.log(list)
    [ 4, 4, 4, 4, 4 ]
    

    for in 其实和for循环一致,因为他们都是取到了index,然后修改list[index]

    这里就不分别看改变item和改变item属性了。

    for of

    改变item本身

    1. const list = [
    2. {name: 'a', count: 1},
    3. 2,
    4. function fn() {
    5. console.log(3);
    6. },
    7. [4,4,4,4],
    8. new Date()
    9. ]
    10. for(let i of list) {
    11. i = 4
    12. }
    13. console.log(list)
    1. [
    2. { name: 'a', count: 1 },
    3. 2,
    4. [Function: fn],
    5. [ 4, 4, 4, 4 ],
    6. 2022-09-13T10:56:11.711Z
    7. ]

    我们发现item无法别更改。

    改变item的属性

    1. const list = [
    2. {name: 'a', count: 1},
    3. 2,
    4. function fn() {
    5. console.log(3);
    6. },
    7. [4,4,4,4],
    8. new Date()
    9. ]
    10. for(let i of list) {
    11. i.count = 4
    12. }
    13. console.log(list)
    1. [
    2. { name: 'a', count: 4 },
    3. 2,
    4. [Function: fn] { count: 4 },
    5. [ 4, 4, 4, 4, count: 4 ],
    6. 2022-09-13T10:57:36.085Z { count: 4 }
    7. ]

    我们发现:结果和forEach一致。他们都是在迭代函数里拿到了item。

    map

    改变item本身

    1. const list = [
    2. {name: 'a', count: 1},
    3. 2,
    4. function fn() {
    5. console.log(3);
    6. },
    7. Symbol(),
    8. [4,4,4,4],
    9. new Date()
    10. ]
    11. list.map(item => {
    12. item = 4
    13. })
    14. console.log(list)
    1. [
    2. { name: 'a', count: 1 },
    3. 2,
    4. [Function: fn],
    5. Symbol(),
    6. [ 4, 4, 4, 4 ],
    7. 2022-09-13T11:01:10.614Z
    8. ]

    我们发现,item无动于衷。

    改变item的属性

    1. const list = [
    2. {name: 'a', count: 1},
    3. 2,
    4. function fn() {
    5. console.log(3);
    6. },
    7. Symbol(),
    8. [4,4,4,4],
    9. new Date()
    10. ]
    11. list.map(item => {
    12. item.count = 4
    13. })
    14. console.log(list)
    1. [
    2. { name: 'a', count: 4 },
    3. 2,
    4. [Function: fn] { count: 4 },
    5. Symbol(),
    6. [ 4, 4, 4, 4, count: 4 ],
    7. 2022-09-13T10:59:53.050Z { count: 4 }
    8. ]

    分析总结

    方式取值方式改变自身改变item的属性
    forlist[index]可以改变list[index]基础类型不可以引用类型可以
    for-inlist[index]可以改变list[index]基础类型不可以引用类型可以
    for-ofitem不可以改变item基础类型不可以引用类型可以
    forEachitem不可以改变item基础类型不可以引用类型可以
    mapitem不可以改变item基础类型不可以引用类型可

     

    为什么不可以改变属性

    改变自身和改变属性,原因是一致的,就是分析一下,真正操作的数据,到底是不是原数据本身。

    这里,主要还是因为迭代器。

    在for-of forEach map 方法中,其实item通过引用类型,指向了原来list里面的每一项。

    我们来看细节:

    1. const list = [
    2. {name: 'a', count: 1},
    3. 2,
    4. function fn() {
    5. console.log(3);
    6. },
    7. Symbol(),
    8. 'sss',
    9. [4,4,4,4],
    10. new Date()
    11. ]
    12. const iter = list[Symbol.iterator]()
    13. const firstElement = iter.next()
    14. console.log(firstElement)
    15. firstElement.value.count = 4
    16. console.log(firstElement)
    17. console.log(firstElement.value === list[0]);
    1. { value: { name: 'a', count: 1 }, done: false }
    2. { value: { name: 'a', count: 4 }, done: false }
    3. true

    对item进行操作,其实是对iterator.next() 指向的对象,也就是 iterator.next().value 进行了操作。

    • 如果原来的值是引用类型,那么iterator.next().value 和 list[index] 表示的是同一个对象。操作的时候当然可以改变原来的item;
    • 如果原来的值是基础类型,那么iterator.next().value 和 list[index] 分别指向了一个基础类型的值。操作的时候不会改变原来的item;

     

    给大家推荐一个实用面试题库

    1、前端面试题库 (面试必备)            推荐:★★★★★

    地址:前端面试题库

  • 相关阅读:
    从 CPU 说起,深入理解 Java 内存模型
    laravel valet
    23、短信登录(基于redis实现共享session登录)
    可视化大屏时代的到来:智慧城市管理的新思路
    Kaggle使用上传的d2l包
    后量子时代,未来密码该何去何从?
    v3 + ts 商城项目的支付模块
    macOS 下 Termius 中文显示为乱码
    js逆向基础篇-某音乐网站-xx音乐
    数据结构 - 链表
  • 原文地址:https://blog.csdn.net/weixin_42981560/article/details/126872743