我在JavaScript中读到这一点,出现了一个常见的混淆点,因为基元的变量是通过值传递的,而对象的变量是通过引用传递的,而在函数参数中,基元和引用都是通过值传递的。 / p>
在我的修修补补过程中,我已经编写了以下代码,但我无法绕过它。
> function setName2(obj) {
... obj.name="matt";
... obj = new Object();
... obj.name="obama";
... }
如果我设置
var person = new Object();
person.name = "michelle";
然后运行
> setName2(person);
我得到了
> person.name;
'matt'
这是有道理的,因为创建的新对象是指向本地对象的指针,因此不会影响全局“人”的属性。
但是,如果我先设置
,该怎么办? var obj = new Object();
obj.name = "michelle";
然后运行
> setName2(obj);
我得到了同样的结果。这是否意味着编译器会识别同名的两个变量(obj global和obj local)作为对堆内不同位置的引用,每个变量都有一些不同的指针关联,或者对这种现象有不同的解释吗?
答案 0 :(得分:2)
JavaScript没有pass-by-reference; 所有都是按值传递的。但是,某些值本身就是对象的引用。这种区别(通过参考传递与参考传递)会导致很多混淆。
清理事实的一个例子:
function f(o) { ... }
var obj = { foo: 42 };
f(obj);
无论你在f
中做什么,obj
总是引用同一个对象,因为参数不是通过引用传递。但是,复制到obj
,的值o
本身就是对象的引用。这就是为什么在函数内部对o
进行的任何属性更改将在obj
返回后显示。
答案 1 :(得分:1)
在函数参数中,原语和引用都是按值传递的。
事实并非如此。函数参数没什么特别的。
function setName2(obj) {
这接受对象的引用作为参数。
obj.name="matt";
这会修改引用指向的对象的name
属性。
obj = new Object();
这将使用对新对象的引用替换对原始对象的引用。
obj.name="obama";
这会修改新对象的name属性。原始对象没有变化。
答案 2 :(得分:1)
这种混淆来自于“通过引用传递”被人们误解或在错误意义上使用的事实。
参数按值传递。这意味着更改方法内的值不会更改原始值。
在基元的情况下,基元的值是其值。 对于对象,对象的值是对它的引用。您可以访问和更改对象的内容,但不能更改引用本身的值。
在其他编程语言中,如C ++或C#,“通过引用传递”意味着您传递: - 对基本类型的引用 - 对对象引用的引用 在这种情况下,不仅可以改变对象的内容,而且可以改变引用本身。
Javascript中没有通过引用传递。
答案 3 :(得分:1)
Javascript使用按值传递。
混淆是对象由引用变量(指针类型)保持。事实上,大多数常见语言(java,javascript等)没有真正的传递引用行为。理解这一点的另一种方法可能是按值传递参考,但正式来说,没有这样的事情。
这意味着当您将对象作为参数传递时,实际上将对 by-value 的引用传递给对象。
function setName2(obj) {
...
}
setName2(person);
此处person
(引用或“指针”,如果您愿意)的内容被 by-value 复制到新的局部变量:obj
。
obj
和person
是包含对同一对象的引用的不同变量。
因此,执行obj = new Object();
会使obj
指向新对象。但是person
不受影响,因为它仍然是一个完全不同的变量。
答案 4 :(得分:0)
我不知道你在哪里阅读,但绝对不是这样。对象通过引用传递,完全停止。它是否是一个函数参数是完全无关的。