Function scope in node ints versus objects?
最近我在node中做了一些编程,我对函数中作用域的处理有点惊讶。我相信现在ES6的范围要严格得多。预期的工作如下:
1 2 3 4 5 6 7 8 | function f(v){ v += 1; return v; } let before = 1; let after = f(before); console.log(after); // This logs 2 (as expected) console.log(before); // This logs 1 (as expected) |
但当我使用对象/字典执行相同操作时,变量的范围似乎超出了函数的范围:
1 2 3 4 5 6 7 8 | function f(v){ v.a += 1; return v; } let before = {a: 1}; let after = f(before); console.log(after.a); // This logs 2 (as expected) console.log(before.a); // This also logs 2 (I was expecting this to still be 1) |
这到底是为什么?为什么当它是一个
javascript函数按值传递所有参数。
在第一种情况下,您有一个原语值(数字是原语)。因此,
从垃圾收集的角度来考虑。你失去了"之前"超出你的范围。无法再访问
在第二种情况下,传递对象引用的值。然后再次返回一个对象引用的值。因此,
现在,再一次,看看垃圾收集器。删除对
Javascript有两种数据类型:Primitive和Object。
在第一个示例中,您传递的是一个基本数据类型(布尔值、空值、未定义、字符串、符号和数字——您的大小写)。当您将这些类型的变量传递给一个函数时,您将传递一个副本——所以任何修改都不会影响初始值/变量,就像在第一个例子中一样。
对于对象数据类型,当您将对象传递到函数中时,您传递的是对该对象值的引用,而不是该值的副本,就像原语一样。所以当您在函数中修改这个函数时,您就是在修改引用。这意味着具有此引用的任何变量也将具有修改后的值,因为它们只是指向最近修改过的值。
这里的范围没有问题。您的代码只是将对象分配给另一个变量,因此每当您编辑对象时,所有分配的变量都会受到影响:
1 2 3 4 5 6 7 | let o1 = { a: 1 }; let o2 = o1; o1.a++; console.log(o2); |