1

我尝试了以下代码,但它会提醒旧对象名称属性?我知道对象是通过引用传递的,但是它是通过引用传递的,那么在函数内部更改的对象也应该在函数外部更改,不是吗?

function setName(obj) {
 obj.name = "raziq";
 obj = new Object();
 obj.name = "abdul";
}
var person = new Object();
setName(person);
alert(person.name); //still yields raziq

如果对象是通过引用传递的,我有点困惑,那么应该提醒新名称为什么它仍然提醒 raziq 作为对象的名称?

4

3 回答 3

3

在您的代码中:

> function setName(obj) {

调用中第一个参数的值分配给局部变量obj。如果传递了一个对象,则obj的值是对该对象的引用。

>   obj.name = "raziq";

这会将值“raziq”分配给传递给obj的对象的name属性。如果name属性不存在,则创建它。

>   obj = new Object(); 

这会将一个新的对象引用分配为obj的值,因此它不再引用传递给函数的对象。

>   obj.name = "abdul";

这会将值“abdul”分配给obj引用的对象(在上面的行中创建和分配的新对象)的name属性(如果该属性不存在,则创建该属性)。

由于没有对该对象的其他引用,因此一旦函数结束,它就可用于垃圾回收。

> }
>
> var person = new Object();

创建一个新对象并将其分配给变量personperson的值是对新对象的引用。

> setName(person);

调用setName并将上面一行创建的对象传递给它。该函数将raziq分配给对象的name属性(见上文)。

> alert(person.name); //still yields raziq

提醒上面创建并分配给person的对象的name属性的值。由于raziq被指定为值,这就是返回的内容。

请注意,在函数中创建了一个新对象,并在赋值语句中创建了一个name属性,但是该对象没有被分配到任何地方,也没有从函数中返回它,所以后面的所有内容:

  obj = new Object();

有效地什么都不做。

请注意,更常见的写法是:

  obj = {};

它的结果与前一行完全相同,但输入更少,使用更广泛,因此可能(略微)更易于阅读和维护。

于 2013-09-30T05:55:12.137 回答
2

JavaScript中没有可用的“通过引用传递”。您可以传递一个对象(也就是说,您可以按值传递对对象的引用),然后让一个函数修改对象内容。

参考来源

在 JavaScript 中,我们有函数,并且我们有传递给这些函数的参数。但是 JavaScript 如何处理你传入的内容并不总是很清楚。当您开始进行面向对象的开发时,您可能会发现自己对为什么有时可以访问值但有时不能访问感到困惑。

当传入像字符串或数字这样的原始类型变量时,值是按值传入的。这意味着在函数中对该变量的任何更改都与函数外部发生的任何事情完全分开。让我们看一下下面的例子:

function myfunction(x)
{
      // x is equal to 4
      x = 5;
      // x is now equal to 5
}

var x = 4;
alert(x); // x is equal to 4
myfunction(x); 
alert(x); // x is still equal to 4

然而,传入一个对象是通过引用传入的。在这种情况下,该对象的任何属性都可以在函数内访问。让我们看另一个例子:

function myobject()
{
    this.value = 5;
}
var o = new myobject();
alert(o.value); // o.value = 5
function objectchanger(fnc)
{
    fnc.value = 6;
}
objectchanger(o);
alert(o.value); // o.value is now equal to 6

那么,当你传入一个对象的方法时会发生什么?大多数人会期望(或者至少我做到了)它将通过引用传递,从而允许该方法访问它所属的对象的其他部分。不幸的是,事实并非如此。看看这个例子:

function myobject()
{
    this.value = 5;
}
myobject.prototype.add = function()
{
    this.value++;
}
var o = new myobject();
alert(o.value); // o.value = 5
o.add();
alert(o.value); // o.value = 6
function objectchanger(fnc)
{
    fnc(); // runs the function being passed in
}
objectchanger(o.add);
alert(o.value); // sorry, still just 6

这里的问题是“this”关键字的使用。这是引用当前对象上下文的方便快捷方式。但是,当将函数作为参数传递时,上下文会丢失。更准确地说,this 现在指的是进行调用的对象的上下文,而不是我们刚刚传入的对象函数。对于独立函数,这将是窗口对象,对于从事件调用的函数,这将是事件对象。

于 2013-09-30T05:35:50.067 回答
2

当您将 分配new Object()给变量 obj 时,您实际上并没有交换原始对象。计算机为您刚刚实例化的对象在内存中创建一个新位置,并为 name 属性分配一个值“abdul”,但这不会更改先前的对象,因为它驻留在内存中的不同位置。新创建的对象永远不会离开函数。

与其将obj变量视为容纳对象的容器,不如将其视为具有对象位置的数字地址的占位符。当您传递person给函数时,您传递的是该地址,而不是对象本身。因此,在函数内部,当您创建新对象时,您将该新对象的地址存储在 placeholder 中obj。函数外部的变量person仍然包含原始对象的地址,而不是您在函数中创建的新对象。

于 2013-09-30T05:10:53.063 回答