前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >console.log分析

console.log分析

原创
作者头像
Yerik
修改2021-08-24 10:50:50
5570
修改2021-08-24 10:50:50
举报
文章被收录于专栏:烹饪一朵云烹饪一朵云

在js的开发过程中,我们不可避免的需要对某些参数的状态进行追踪,这个时候就回使用console.log这个函数,但这个简单函数背后你所不知道的一面

这个函数最常规的使用方式就是在代码的任何部分调用console.log,然后可以在浏览器的开发者控制台里,看到这个函数调用的那一瞬间你指定的变量或表达式的值,可事实真的是这样吗?眼见真的为实吗?

打印信息是同步的?

我们来看看这段代码,应该不难猜测运行之后的结果吧?

代码语言:txt
复制
    testConsole() {
      let yerik = {
        shu: 1,
      };
      console.log(yerik);
      yerik.NAUG = 111;
      console.log(yerik);
    },
运行结果1.png
运行结果1.png

这个方式就是我们常见的一种变量追踪手法,我愿称之为"面向print"开发

从这个例子来看似乎没什么问题,那么我们让这个变量变得更加复杂一些

代码语言:txt
复制
    testConsole() {
      let yerik = {
        shu: { s: 1, h: 2, u: 0, n: 0, a: 1, U: 2, g: 3 },
      };
      console.log(yerik);
      yerik.NAUG = 111;
      console.log(yerik);
    },

我们将shu这个属性从原来的整型变成object之后,再用console打开,欸,奇怪了,讲道理应该是不会在第一行就显示带有NAUG这个属性的啊,为什么在控制台上面存在呢?

运行结果2.png
运行结果2.png

眼见真不为实

进一步分析

in

判断对象里面有没有这个属性,最好的方式就是遍历一遍属性,有就是有,没有就是没有

代码语言:txt
复制
    testConsole() {
      let yerik = {
        shu: { s: 1, h: 2, u: 0, n: 0, a: 1, U: 2, g: 3 },
      };
      console.log(yerik);
      Object.keys(yerik).forEach((item) => console.log(item));
      console.log("NAUG" in yerik);
      yerik.NAUG = 111;
      console.log(yerik);
      console.log("NAUG" in yerik);
    },
运行结果3.png
运行结果3.png

这么一看还真没呀,嗷,这个是写代码写多了,瞎了吗!!!!那个圈圈里面的属性不是写的明明白白吗!?!?

观察到!

两次的实验下来,突然发现有个感叹号logo,可能是翻译的原因,读起来很拗口,不过有个关键字倒是让人很兴奋,"已更改",那么我们接下来就是寻找已更改的原因了

运行结果4.png
运行结果4.png

联想到“提升”

依稀记得在学习的过程中,接触过作用域,这玩意说简单点就是你的程序存放变量、变量值和函数的地方。根据作用范围不同可以分为全局作用域和局部作用域,这次遇到的问题是在各自的作用域内,声明和赋值的位置是不是在执行的过程中被“优化”过?我们看看以下这段代码,观察下作用域的工作过程

代码语言:txt
复制
    workspace() {
      console.log(study);
      var study = "神奇js引擎";
      function testSpace() {
        console.log(study);
        var study = "20210823";
        console.log(study);
      }
      testSpace();
      console.log(study);
    },
运行结果5.png
运行结果5.png

在这里我们看到了有两个undefined意味着什么呢?未赋值,虽然显示的是未定义,但实际上已经定义了,不然不可能出现对应的回显。这个执行的过程的代码实际上是这样的?

代码语言:txt
复制
var study
console.log(study)
study = "20210823"

我们习惯将var study="20210823";看做是一个声明,而实际上javascript引擎并不这么认为。它将var study和study = "20210823"看做是两个单独的声明,第一个是编译阶段的任务,而第二个则是执行阶段的任务。

基于这个分析,我们再回过头来看下原来的代码,我们虽然是在代码中间进行赋值,但是由于“作用域提升”的存在,导致我们看到了这个NAUG的存在

运行结果6.png
运行结果6.png

接下来我们还需要解决为何通过遍历或者检索都没有发现对应NAUG的存在这个问题。

事实上,在stackoverflow上面,有个老哥回答了这个问题,我的理解是这个NAUG本来是不存在的,但是当我们点开这个对象的时候,会被再渲染一次,毕竟log都只打当前状态,不是代码当时的状态,从而出现了我们观察到的现象

各位你们的看法是怎样的呢?:)

参考资料

  1. https://developer.mozilla.org/zh-CN/docs/Web/API/Console/log
  2. https://nodejs.org/docs/latest/api/console.html#console_console_log_data
  3. https://stackoverflow.com/questions/17546953/cant-access-object-property-even-though-it-shows-up-in-a-console-log

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 打印信息是同步的?
  • 进一步分析
    • in
      • 观察到!
        • 联想到“提升”
        • 参考资料
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档