所有结果的运行环境都是Chrome,不同的浏览器运行结果可能不同a值为“赋值后”,第二行打印出的值为属性a,但是是Undefinedlettest={}console.log(test)console.log(test.a)test.a="afterassignment"深入分析为什么console.log(Object)看起来像unreal?如果我们打印一个对象,chrome会默认省略掉具体信息,只显示一个Object。这是引用的快照,不是快照的内容。如果不点击打开,引擎就不会去引用的地址去取内容letobj={a:"a",b:{bb:'bb'},timeOut:"now"}console.log(obj)console.log(obj.a)console.log(JSON.stringify(obj))obj.a="amodified"obj.b.bb="bbmodified"console.log(obj)当我们点击这个对象展开的时候,chrome会重新获取这些引用的值,但是当我们点击这个对象展开的时候,代码已经执行过了,所以重新获取修改后的值,也就是其实相当于一种懒加载,这就是为什么可以在控制台无限查看Object的原型了。setTimeout验证Chrome的值模式下面的代码会有两种不同的输出,只取决于你点击打开打印的Object的时间letobj={timeOut:"now"}console.log(obj)console.log(obj)console.log(obj.timeOut)setTimeout(()=>{obj.timeOut="fivesecondslater"},5000)第一种情况,不用等,直接点击展开两个Object,timeOut现在,连你等5,折起来再展开拉值。该值将永远不会再改变。Chrome应该会存储这次拉取的数据,并且不会再次更改。第二种情况是展开第二个Object的时候,等了5秒才展开得到准确的对象信息——console.log(JSON.stringify(obj))这个方法可以强制显示当前结果,序列化将对象转化为字符串,并使用console.log是异步的还是同步的来强制执行“快照”是不准确的。这不是异步和同步的问题。Syntax”部分)添加到JavaScript。这是针对不同的浏览器。例如,Chrome由Devtool控制台提供,而Firefox由Firebug控制台提供。《你不知道的javascript中卷》中的部分指定没有规范或设置指定console.*方法如何工作的要求——它们不是JavaScript的正式部分,而是由添加到JavaScript的主机环境(参见本书的“类型和语法”部分)定义的。因此,不同的浏览器和JavaScript环境可以为所欲为,这有时会造成混乱。特别是在某些情况下,某些浏览器的console.log(..)不会立即输出传入的内容。造成这种情况的主要原因是在许多程序中(不仅仅是JavaScript),I/O是一个非常缓慢的阻塞部分。因此,(从页面/UI的角度来看)浏览器可以通过在后台异步处理控制台I/O来提高性能,而用户甚至可能没有意识到它正在发生。下面这种情况不是很常见,但有可能发生,从中(不是从代码本身而是从外部)可以观察到:PS:你可以试试这个vara={index:1};//然后console。日志(一);//??//然后a.index++;我们通常认为console.log(..)语句刚执行时,会看到a对象的快照,打印类似{index:1}的东西,然后在下一条语句a.index++时修改被执行了,这句话的执行会严格在a的输出之后。在大多数情况下,上述代码在开发者工具控制台输出的对象表示是符合预期的。但是,当这段代码运行时,浏览器可能认为它需要将控制台I/O延迟到后台。这种情况下,当浏览器控制台输出对象内容时,a.index++可能已经执行完毕,所以会显示{index:2}。究竟什么时候控制台I/O会被延迟,或者即使它甚至是可观察到的,也有待商榷。如果在调试期间您看到一个对象在console.log(..)语句之后被修改并且您看到意外的结果,请注意这可能是由于此I/O的异步性质。在这种罕见的情况下,最好的办法是在JavaScript调试器中使用断点,而不是依赖控制台输出。一个次优的解决方案是将对象序列化为字符串以强制执行“快照”,例如通过JSON.stringify(..)。
