【Web前端问题】Js中修改数组中的数据与console.log问题

这是一个修改array与console.log的问题
为什么console.log会输出在他后面才改变的数据结果?

      let arr = [{id: 1}, {id: 2}];

console.log(arr); //输出: [{id: 666}, {id: 2}]

arr[0].id = 666;

代码执行顺序不是从上至下的吗?
为什么输出的会是修改后的值?
然后我再试了修改数组中的基本数据类型却不会这样.

    let arr = [1, 2];

console.log(arr); //输出: [1, 2]

arr[0] = 666;

console.log(arr); //输出: [666, 2]

然后我又试了Object

    let obj = {id: 1};

console.log(obj); //输出: {obj: 1}

obj.id = 666;

console.log(obj); //输出: {obj: 666}

数组中的对象就这么特殊吗? 比在前面的代码执行还快? 其中的原理究竟是什么?

其实这个问题找了很多地方都没找到,主要是问题也不太会表达. 类似的也搜不到, 答案一般都是教你怎么更改数组中元素这些操作.
但是这种关于输出修改顺序的问题却没有找到.

不过在Stack Overflow中我看到一个回答
说是数组中对象树的修改比console.log执行的快,因为是英文的, 翻译可能有点出入.

恳请各位大佬解答一下.

回答:

没有那么复杂,我估计是 console.log() 遇到对象时会默认展开并显示第一层,也就是你的第二段代码,如下:
clipboard.png
而对有两层属性的对象(或者说对象里又有一个子对象),console.log()并不会继续展开,你的第一段代码如下:
clipboard.png
你只能手动展开,手动展开的速度比代码修改内部属性的速度快是不可能的,所以等你手动展开时看到的是后来代码修改后的内容,如下:
clipboard.png
但是如果console.log()非对象时,就不会出现这些问题了,如下:
clipboard.png

总结:chrome devtools 的 console 中 console.log js 对象时会展开一层,如果这一层中还有对象则不会展开,只会展示类似{...}Array(2)等样子,但会保存该子对象的引用,用于支持手动展开,手动展开的子对象的内容可能不是 console.log() 父对象时的内容,而是展示时当时的内容。

纯属个人多次尝试后的猜测,未经查阅相关资料,不保证专业性

回答:

因为你console的是一个引用地址,而不是一个值
console出来的东西会根据地址里的内容变化

图片描述

看了这张图应该会明白一些

回答:

跟console.log没啥关系,你得先知道引用对象

回答:

这是chrome的console的机制;
console.log()的执行是同步的,不过在chrome的控制台里输出的是对象的快照,当你在控制台打开那个快照时它是去取那个对象地址里的内容的,所以会显示修改后的结果。
你说的第二种情况也是一样的。

回答:

  • 这个你想多了跟语言没什么关系,执行肯定是按顺序执行的没问题
  • 只是打印的只是一个对象的引用,就像薛定谔的猫,你没有打开它它的内容是不确定的,因为内容是可以由后面代码改变的
  • 教你个方法,先输出一个数组,定时几秒后再改变这个数组,你会发现在定时器改变前点击打印的数组,查看数组的内容时这就是原本的数组,如果你等定时器改变了数组的内容再打开这个数组就是改变后的内容
  • 你可以理解为console最开始打印的那个缩写只是个引用,只有点开这个数组才会找出这个数组的具体内容显示在浏览器上,这时这个打印就是个字符串了,即使后面有逻辑改变它它也不会变了

回答:

可以看下这个回答https://bbs.csdn.net/topics/3...
使用JSON.stringify转换,然后再转回来,可以起到一种类似固化得效果

回答:

console.log()有惰性求值问题.

以上是 【Web前端问题】Js中修改数组中的数据与console.log问题 的全部内容, 来源链接: utcz.com/a/142742.html

回到顶部