3

我正试图围绕这个“争论传递”的想法。在我正在阅读的一本书中,它指出参数仅通过值传递,而不是通过引用传递。

function addTen(num) { 
   num + = 10;
   return num; 
} 


var count = 20; 
var result = addTen(count); 
alert(count); // 20 - no change 
alert(result); // 30

上面的例子很清楚,但下面的例子让我很困惑。

当 person 被传递给 setName 函数时,它不是镜像局部变量 'obj' 并沿函数中的语句向下流动吗?即 person 首先被设置为属性名称,然后它被分配给一个新的对象,最后这个新创建的人对象被分配属性'Gregg'????

为什么你得到'尼古拉斯'!!!!

function setName(obj) {
    obj.name = "Nicholas"; 
    obj = new Object(); 
    obj.name = "Greg"; 
}        

var person = new Object(); 
setName(person); 
alert(person.name); //" Nicholas"
4

5 回答 5

3

Objects are passed to function as a copy of the reference. Now what happens in your example is next:

var person = new Object();     

function setName(obj) { // a local obj* is created, it contains a copy of the reference to the original person object
    obj.name = "Nicholas"; // creates a new property to the original obj, since obj here has a reference to the original obj
    obj = new Object(); // assigns a new object to the local obj, obj is not referring to the original obj anymore
    obj.name = "Greg"; // creates a new property to the local obj
}

setName(person);
alert( person.name); //" Nicholas"

* = obj is a local variable containing a value, which is a reference to the original obj. When you later change the value of the local variable, it's not reflecting to the original object.

于 2013-07-06T13:42:58.220 回答
2

Everything is pass-by-value in JavaScript. When you pass anything as an argument, JS makes a copy of that and sends it to the function. When an Object is passed, JS copies the reference of that object into another variable and passes that copied variable to the function. Now, since the passed variable is still pointing to the object, you can alter its properties using the . or [] notation. But if you use new to define a new object then that variable just points to the new reference.

function setName(obj) {
    obj.name = "Nicholas"; // obj pointing to person reference
    obj = new Object();  // obj now pointing to another reference
    obj.name = "Greg"; // you have changed the new reference not person reference
}        

var person = new Object(); // person pointing to person reference
setName(person); 
alert( person.name); //" Nicholas"
于 2013-07-06T13:49:08.497 回答
2

你得到"Nicholas"的正是因为 JavaScript 永远不是“通过引用”。如果是,您将能够person从任何位置更新变量。事实并非如此,因此new Object()函数中的 in 不会改变外部person变量。

但也不是变量引用对象本身,而是变量持有一种特殊类型的引用,让您无需直接访问内存即可更新对象。

这就是为什么尽管 JavaScript 总是“按值”,但您永远无法获得对象的完整副本。您只是获得了该特殊参考的副本。因此,您可以操作通过引用副本传递的原始对象,但实际上不能通过引用替换它。

于 2013-07-06T13:40:40.207 回答
1

参数是按值传递的,对于对象来说,这意味着该值是对该对象的引用的副本。

这和你做一个简单的赋值是一样的,也是按值:

// a variable that contains a reference to an object:
var person = new Object();
// another variable, that gets a reference to the same object:
var people = person;
// a function call with a reference to the object:
setName(person);

在函数中,参数是一个局部变量,它独立于用于将引用发送到函数的变量,但它引用的是同一个对象:

function setName(obj) {
  // as the variable references the original object, it changes the object:
  obj.name = "Nicholas";
  // now the variable gets a reference to a new object
  obj = new Object();
  // the new object is changed
  obj.name = "Greg";
}
于 2013-07-06T13:51:08.787 回答
0

通过引用传递意味着:

function a(obj) {
    obj = 3;
}

var test = new Object();
a(test);
console.log(test); //3, so I have lost the object forever

IE 甚至变量赋值对调用者都是可见的。

当然,如果目标函数修改了传递给它的对象,那么对对象本身的这些修改将对调用者可见。

于 2013-07-06T13:41:13.727 回答