什么?console.log打印出的数据不对?
创始人
2024-01-28 21:30:53

背景

都怪我年轻不懂事,调试代码只会用console.log。那么,就在今天,出事儿了!

看图说话。上面的111222后面跟的数据竟然不一致?

在我的认知中,JSON里面的parsestringify方法只是类型的转换啊,怎么还把值给我变了!这不是坑人吗!

经过高人指点,我才明白,

console.log()打印出来的内容并不是一定百分百可信的内容。> 一般对于基本类型numberstringbooleannullundefined的输出是可信的。> 但对于Object等引用类型来说,则就会可能出现上述异常打印输出。

那么,既然有“可能”性,到底什么时候会出现异常呢?也即我上面的截图结果的出现逻辑是什么呢?

前置知识

1.引用类型的存储需要内存的栈区和堆区(堆区是指内存里的堆内存)共同完成,栈区内存保存变量标识符和指向堆内存中该对象的指针。
2.引用类型可以拥有属性和方法,并且是可以动态改变的。
3.引用类型的比较是引用的比较。

上图异常出现的逻辑解析

1.console.log打印一个对象时,是指向一片内存地址。111后面打印了一个Object对象,所以指向的是内存地址。
2.而222后面的是经过了对象序列化的数组,属于深拷贝,并不会跟着对象的改变而改变。
3.我在使用了console.log之后,使用AJAX更改了this.selectedAttrsnameEn的数据,从“aaa”改为“”
4.此时进入控制台,在点开三角箭头之前,能看到的都是未修改的值。因为console.log日志输出后无法回撤或者更新。
5.但是点击了111后面的三角箭头后,此时才会请求此内存地址下的内容,发现已修改为“”。并且点击已被序列化的222的内容时,看到的是修改前的值。
6.也就是说,222后面跟的才是console.log此时此刻此对象的值,111后面的详细内容是经过后期代码修改了的。

所以啊,在需要用console.log调试时,尽量不要直接输出对象,先将对象序列化JSON.stringify()为字符串再输出。或者使用打断点(debugger)的方式来调试。

总之,可以得出一个结论:chrome调试工具的那个三角形点开的时候才会拿着内存地址去取对象的值。

举一个例子:

//执行以下代码
let obj={age:20} 
console.log(obj)
obj.age=30 

执行结果:

不展开obj对象,看到的是我们预期的20,展开对象,看到的却是30。如果我们输出一个字段很多的对象,那必须展开才能看到属性值,展开后,看到的值是点击“展开”那一刻时对象的值,而非console执行那时候的值。

原因分析:

  • 不展开对象看时,console.log()是按照代码执行顺序,同步地输出了对象当时的快照。所以我们看到的是预期的值。
  • 展开对象时,它其实是重新去内存中读取对象的属性值,此时对象属性已被更改,所以展开对象后,看到的不是好久以前的预期值了。

console到底是什么

console 对象提供对浏览器调试控制台的访问。

console 挂载在 window 对象上,ECMAScript 中并没有规定 console 该如何实现,因为它不属于 javascript 的语言标准。每个浏览器都有自己的实现,并不约而同的把它挂载到 window 对象上。所以 console 对象的方法并不是每个浏览器都会实现,行为也可能会有略微差异。

console的常用API

1.console.log //按照参数传入的顺序打印一个或者多个变量。

如果打印的是Object / Array / Function 等非基本类型,在控制台显示的是该变量的引用,也就是说后续对变量的修改也会体现在控制台。console 初始打印的是执行到console.log语句时的变量值,虽然是引用类型,但是控制台并不会实时追踪值的变化,只有用户主动触发 ▶(查看详情)才会展示变量的当前值。后续值的更改不会再反应到控制台,也就是说一旦查看详情,控制台对变量的跟踪就“断开”了。

如果就想打印某个 object 执行到 console 的当前值怎么办?

1)console.log(JSON.parse(JSON.stringify(object)))> 2)深度克隆 object (推荐)

2.console.dir //在控制台打印出 obj 带有三角形的层次结构列表,可查看子对象的内容。

跟 log 方法的区别是不显示简略信息,只显示一个 ▶ 和对象参数的 constructor

3.console.time(label)> console.timeEnd(label) //打印出timetimeEnd 之间JS的执行耗时

4.console.error //打印出错误信息

一般底色为红色,并会展示错误位置的调用栈 浏览器的 JS 报错用的就是 console.error 。

…更多console工具可自行上网冲浪查询。

那问题来了,调试JS代码的时候你只会用console吗?

Chrome DevTools 开发者工具

1. 控制台中直接访问页面元素

在元素面板Elements选择一个元素,然后在控制台输入$0,就会在控制台中得到刚才选中的元素。如果页面中已经包含了 jQuery,你也可以使用$($0)来进行选择。也可以反过来,在控制台输出的 DOM 元素上右键选择 Reveal in Elements Panel 来直接在 DOM 树中查看。

2. 访问最近的控制台结果

在控制台输入$_可以获控制台最近一次的输出结果。

3. 使用 console.dir

console.dir(object)/dir(object) 命令可以列出参数 object 的所有对象属性。

4. 清空控制台历史记录

可以通过下面的方式清空控制台历史:

  • 在控制台右键,或者按下 Ctrl 并单击鼠标,选择 Clear Console。
  • 在脚本窗口输入 clear()执行。
  • 在 JavaScript 脚本中调用 console.clear()。
  • 使用快捷键 Cmd + K (Mac) Ctrl + L (Windows and Linux)。

5. 切换主题

Chrome 提供了 亮&暗 两种主题,当你视觉疲劳的时候,可以 switch 哦, 快捷键 ctrl+shift+p ,打开 Command Menu,输入 theme ,即可选择切换。

…更多Chrome调试技巧和一些快捷键期待你的一起探索喔~~

最后

整理了75个JS高频面试题,并给出了答案和解析,基本上可以保证你能应付面试官关于JS的提问。



有需要的小伙伴,可以点击下方卡片领取,无偿分享

相关内容

热门资讯

埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
上海有几个区 最新上海16区划... 你平常会使用地图吗?一幅标准的地图可以帮助我们解决很多问题。自然资源部最新公布了长三角标准地图,上海...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
男生摸女生胸 同桌把我带到卧室... 所谓“酒色财气”,酒与色往往是连在一起的,澳洲有个医学生,就因为两次酒后猥亵自己的同学,几乎葬送了自...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...