热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

[JavaScript]多数前端工程师都没注意到的一个关于console.log()的坑

[JavaScript]多数前端工程师都没注意到的一个关于console.log()的坑请阅读以下代码并猜测结果:functiontest(){le

[Javascript] 多数前端工程师都没注意到的一个关于console.log()的坑
请阅读以下代码并猜测结果:

      function test() {
        let obj = {}, arr=[]
          for(var i = 0; i <4; i++) { obj.first = i obj.secOnd= i+1 obj.three = i+2 arr.push(obj) }
        console.log(arr)
      }
      test()

输出结果为:
这里写图片描述
为什么输出结果不是以下这个?
这里写图片描述

我要说的坑不是这个,因为相信这个引用类型的赋值问题很多伙伴都能轻松解决。以下提供两种解决方案:
(方法一),将let obj={}移到for循环中,每次循环创建一个新对象:

      function test() {
        let arr=[]
          for(var i = 0; i <4; i++) { let obj = {}
            obj.first = i
            obj.secOnd= i+1
            obj.three = i+2
            arr.push(obj)
        }
        console.log(arr)
      }
      test()

能得到预期结果:
这里写图片描述

(方法二):使用ES6新特性Object.assign,轻松实现深复制,这样的好处是不用每次都创建一个新对象:

      function test() {
        let obj= {}, arr=[]
          for(var i = 0; i <4; i++) { obj.first = i obj.secOnd= i+1 obj.three = i+2 arr.push(Object.assign({}, obj))
        }
        console.log(arr)
      }
      test()

同样能得到预期结果:
这里写图片描述

问题都解决了,那么我说的坑是什么呢?
接下来我们将解决了以上问题的代码作出以下修改,将console.log移到循环中,如下:

      function test() {
        let obj= {}, arr=[]
          for(var i = 0; i <4; i++) { obj.first = i obj.secOnd= i+1 obj.three = i+2 arr.push(Object.assign({}, obj))
            console.log(arr)
        }
      }
      test()

请先预测一下结果是什么再看以下答案。
运行结果为:

这里写图片描述
每次循环输出的都是最后的值,是不是有点惊讶?我们再来看一点更惊讶的,在输出数组前数组一下数组的长度console.log(arr.length),如下:

      function test() {
        let obj= {}, arr=[]
          for(var i = 0; i <4; i++) { obj.first = i obj.secOnd= i+1 obj.three = i+2 arr.push(Object.assign({}, obj))
            console.log(arr.length)
            console.log(arr)
        }
      }
      test()

同样,先预测运行结果再看以下答案。
运行结果为:
这里写图片描述
第一次循环输出数组的长度是1,看起来也是只有一个对象,这很符合预期;但是为什么展开后,里边会有四个对象?第二次循环数组长度是2,看起来有两个对象,这符合预期,但是点开后为什么里边也是有四个对象?这就是我说的坑!!!

原因:
使用console.log()输出引用类型值时,console.log的实际执行会推迟,相当于“惰性”求值,遇上数组、对象这样的引用类型就出上面的问题了,也就是我们点击箭头打开的时候,才会输出真正的值,而这时候循环早就已经执行完了,所以输出的会是循环执行完后的结果!

测试
我们可以将arr转成非引用类型的数据格式,来证明我们的想法,如下:

      function test() {
        let obj= {}, arr=[]
          for(var i = 0; i <4; i++) { obj.first = i obj.secOnd= i+1 obj.three = i+2 arr.push(Object.assign({}, obj))
            console.log(arr.length)
            console.log(JSON.parse(JSON.stringify(arr)))
        }
      }
      test()

这里写图片描述
显然,结果已经符合预期,猜测正确!!

完结~ 午休一会~~~


推荐阅读
  • 本文详细介绍了JavaScript中数组的各种操作方法,包括创建、检测、字符串转换、添加和删除元素、翻转与排序、连接与分割、位置查找、迭代处理以及数组的缩小方法等,适合初学者深入理解JavaScript数组的使用。 ... [详细]
  • JavaScript 中创建对象的多种方法
    本文详细介绍了 JavaScript 中创建对象的几种常见方式,包括对象字面量、构造函数和 Object.create 方法,并提供了示例代码和属性描述符的解释。 ... [详细]
  • 本文详细介绍如何在VSCode中配置自定义代码片段,使其具备与IDEA相似的代码生成快捷键功能。通过具体的Java和HTML代码片段示例,展示配置步骤及效果。 ... [详细]
  • 本文探讨了如何解决在使用CoffeeScript定义类时,实例化后对象为空的问题,并提供了解决方案。 ... [详细]
  • 嗨,我正在为我的api调用使用axious,并且无法在nodejs中解析我的数据,不确定为 ... [详细]
  • 前言--页数多了以后需要指定到某一页(只做了功能,样式没有细调)html ... [详细]
  • 本文详细介绍了Akka中的BackoffSupervisor机制,探讨其在处理持久化失败和Actor重启时的应用。通过具体示例,展示了如何配置和使用BackoffSupervisor以实现更细粒度的异常处理。 ... [详细]
  • 本文详细介绍了Java编程语言中的核心概念和常见面试问题,包括集合类、数据结构、线程处理、Java虚拟机(JVM)、HTTP协议以及Git操作等方面的内容。通过深入分析每个主题,帮助读者更好地理解Java的关键特性和最佳实践。 ... [详细]
  • JavaScript中属性节点的类型及应用
    本文深入探讨了JavaScript中属性节点的不同类型及其在实际开发中的应用,帮助开发者更好地理解和处理HTML元素的属性。通过具体的案例和代码示例,我们将详细解析如何操作这些属性节点。 ... [详细]
  • 本文探讨了如何在给定整数N的情况下,找到两个不同的整数a和b,使得它们的和最大,并且满足特定的数学条件。 ... [详细]
  • 本文介绍如何在PostgreSQL数据库中正确插入和处理JSON数据类型,确保数据完整性和避免常见错误。 ... [详细]
  • 本文详细介绍了JavaScript中数组的两个重要高阶函数:map()和reduce()。map()用于将数组中的每个元素通过指定的函数进行处理并返回一个新的数组,而reduce()则用于对数组中的元素进行累积计算,最终返回一个单一值。 ... [详细]
  • 本文详细探讨了JavaScript中的闭包与柯里化技术,这两者是函数式编程的重要组成部分,对提升代码的灵活性和可维护性具有重要作用。 ... [详细]
  • 本文介绍如何使用JavaScript计算并显示指定年份的周数以及每周的起止日期,例如2015年的第1周从1月1日至1月7日,第2周从1月8日至1月15日。 ... [详细]
  • 本文详细探讨了使用纯JavaScript开发经典贪吃蛇游戏的技术细节和实现方法。通过具体的代码示例,深入解析了游戏逻辑、动画效果及用户交互的实现过程,为开发者提供了宝贵的参考和实践经验。 ... [详细]
author-avatar
死了才能爱_403
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有