前几天,我在Angular 6应用程序中发生了一个事件,其中涉及一些看起来像这样的代码:
console.log('before:', value);
this.changeValue(value);
console.log('after:', value);
changeValue()以某种方式修改值。我希望在调用changeValue()之前,然后在修改后的值之前,在控制台中看到未修改的值。相反,我在修改前后看到了修改后的值。
我猜它证明了我的changeValue()函数可以正常工作,但是它也向我表明console.log()是异步的,也就是说,它不会立即将值打印到控制台。它会稍等...直到最终打印出该值时,它就是当时的值。换句话说,上面对console.log()的第一次调用一直等到对changeValue()的调用之后才打印,并且当它更改时,该值已经更改。
所以我可以正确地推断console.log()是异步的。如果是这样,那为什么呢?调试时会引起很多混乱。
答案 0 :(得分:0)
否,console.log()是同步的。实际上是您的changeValue()函数无法按照您的想法工作。
首先,JavaScript不会通过引用传递变量,而是通过pointer to object传递变量(许多其他语言也是如此)。因此,尽管函数内部的变量value
和外部作用域的变量value
都拥有相同的对象,但是它们仍然是单独的变量。对对象进行突变会影响两个变量,但是直接分配给一个变量不会会影响另一个变量。例如,这显然不会起作用:
function changeValue(x) { x = 123; }
第二,在JavaScript中,简写分配a += b
不会使a
中存储的现有对象发生变化。相反,它的工作原理与a = a + b
完全一样,并为变量分配了一个 new 对象。如上所述,这仅影响变量 inside 的功能,而不会影响外部的变量,因此您的更改将在函数返回后丢失。
更多示例:
function willwork(obj) { obj.foo = "bar"; }
function willwork(obj) { obj["foo"] = 1234; }
function willwork(obj) { obj.push("foo"); }
function wontwork(obj) { obj = "foo"; }
function wontwork(obj) { obj += 123; }
function wontwork(obj) { obj = obj + 123; }