在js的开发过程中,我们不可避免的需要对某些参数的状态进行追踪,这个时候就回使用console.log
这个函数,但这个简单函数背后你所不知道的一面
这个函数最常规的使用方式就是在代码的任何部分调用console.log,然后可以在浏览器的开发者控制台里,看到这个函数调用的那一瞬间你指定的变量或表达式的值,可事实真的是这样吗?眼见真的为实吗?
打印信息是同步的?
我们来看看这段代码,应该不难猜测运行之后的结果吧?
testConsole() {
let yerik = {
shu: 1,
};
console.log(yerik);
yerik.NAUG = 111;
console.log(yerik);
},
这个方式就是我们常见的一种变量追踪手法,我愿称之为"面向print"开发
从这个例子来看似乎没什么问题,那么我们让这个变量变得更加复杂一些
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
这个属性的啊,为什么在控制台上面存在呢?
眼见真不为实
进一步分析
in
判断对象里面有没有这个属性,最好的方式就是遍历一遍属性,有就是有,没有就是没有
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);
},
这么一看还真没呀,嗷,这个是写代码写多了,瞎了吗!!!!那个圈圈里面的属性不是写的明明白白吗!?!?
观察到!
两次的实验下来,突然发现有个感叹号logo,可能是翻译的原因,读起来很拗口,不过有个关键字倒是让人很兴奋,"已更改",那么我们接下来就是寻找已更改的原因了
联想到“提升”
依稀记得在学习的过程中,接触过作用域,这玩意说简单点就是你的程序存放变量、变量值和函数的地方。根据作用范围不同可以分为全局作用域和局部作用域,这次遇到的问题是在各自的作用域内,声明和赋值的位置是不是在执行的过程中被“优化”过?我们看看以下这段代码,观察下作用域的工作过程
workspace() {
console.log(study);
var study = "神奇js引擎";
function testSpace() {
console.log(study);
var study = "20210823";
console.log(study);
}
testSpace();
console.log(study);
},
在这里我们看到了有两个undefined
意味着什么呢?未赋值,虽然显示的是未定义,但实际上已经定义了,不然不可能出现对应的回显。这个执行的过程的代码实际上是这样的?
var study
console.log(study)
study = "20210823"
我们习惯将var study="20210823";看做是一个声明,而实际上javascript引擎并不这么认为。它将var study和study = "20210823"看做是两个单独的声明,第一个是编译阶段的任务,而第二个则是执行阶段的任务。
基于这个分析,我们再回过头来看下原来的代码,我们虽然是在代码中间进行赋值,但是由于“作用域提升”的存在,导致我们看到了这个NAUG的存在
接下来我们还需要解决为何通过遍历或者检索都没有发现对应NAUG的存在这个问题。
事实上,在stackoverflow上面,有个老哥回答了这个问题,我的理解是这个NAUG本来是不存在的,但是当我们点开这个对象的时候,会被再渲染一次,毕竟log都只打当前状态,不是代码当时的状态,从而出现了我们观察到的现象
各位你们的看法是怎样的呢?:)
参考资料
- https://developer.mozilla.org/zh-CN/docs/Web/API/Console/log
- https://nodejs.org/docs/latest/api/console.html#console_console_log_data
- https://stackoverflow.com/questions/17546953/cant-access-object-property-even-though-it-shows-up-in-a-console-log