我尝试了以下代码,但它会警告旧的对象名称属性?我知道对象是通过引用传递但它通过引用传递然后在函数内部更改的对象也应该在函数外部更改不是吗?
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作为对象的名称?
答案 0 :(得分: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();
创建一个新对象并将其分配给变量 person 。 person 的值是对新对象的引用。
> setName(person);
调用 setName 并将其传递给上面一行中创建的对象。该函数将 raziq 分配给对象的 name 属性(参见上文)。
> alert(person.name); //still yields raziq
警告上面创建并分配给 person 的对象的 name 属性的值。由于 raziq 被指定为值,因此返回的内容。
请注意,在函数中创建了一个新对象,并在赋值语句中创建了 name 属性,但该对象未被分配到任何位置或从函数返回,因此一切后:
obj = new Object();
实际上什么都不做。
请注意,更常见的是写:
obj = {};
与前一行的结果完全相同,但输入次数较少,使用范围更广,因此很容易(略微)更容易阅读和维护。
答案 1 :(得分:2)
将new Object()
分配给变量obj时,实际上并没有交换原始对象。计算机在内存中为您刚刚实例化的对象创建一个新点,并为name属性指定值“abdul”,但这不会更改前一个对象,因为它位于内存中的不同位置。新创建的对象永远不会离开函数。
不要将obj
变量视为容纳对象的容器,而应将其视为具有对象位置的数字地址的占位符。当您将person
传递给函数时,您传递的是该地址,而不是对象本身。因此,在函数内部,当您创建新对象时,您将该新对象的地址存储在占位符obj
中。函数外部的变量person
仍然包含原始对象的地址,而不是您在函数中创建的新地址。
答案 2 :(得分: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'关键字。它是引用当前对象上下文的简便方法。但是,当将函数作为参数传递时,上下文将丢失。更准确地说,这现在指的是调用对象的上下文而不是我们刚刚传入的对象的函数。对于独立函数,这将是窗口对象,对于从事件调用的函数,这将是事件对象。