JavaScript - 通过引用传递对象

4

可能有重复:
如何在数组内存储对变量的引用?

考虑以下代码:

var a = 'cat';
var b = 'elephant';
var myArray = [a,b];

a = 'bear';

myArray[0]仍然会返回'cat'。有没有一种方法可以在数组中存储引用而不是克隆,这样myArray[0]就会返回'bear'?


不过,在这种情况下,您可能希望更新数组:myArray[0]='bear'。我找不到创建这样的引用的原因。 - lu1s
因为每次我编辑数组中对象的属性时,都必须手动更新数组。 - indieman
当你想要“编辑数组中对象的属性”时,为什么不直接编辑数组呢? - jahroy
2
你正在改变变量a所引用的对象。你并没有改变变量a所指向的对象,因此它无法正常工作... - jahroy
5个回答

7

虽然我同意其他人的观点,认为您应该只使用myArray[0] = whatever,但如果您真的想实现您试图达到的目标,您可以确保数组中的所有变量都是对象。

var a = {animal: 'cat'},
    b = {animal: 'elephant'};

var myArray = [a, b];

a.animal = 'bear';

myArray[0].animal现在是“熊”。


1
没错。但是如果你创建一个新对象,然后将其赋值给a(使用newObject代替a.animal = newObject),它不会起作用。这就是我认为OP(或者也许是我自己)感到困惑的地方。 - jahroy

6
不,JavaScript不以那种方式处理引用。

1

不可能的。JavaScript 不支持这样的引用。

只有对象被存储为引用。但我怀疑这不是你想要的。


那么你的意思是,如果我设置 $a = 'foo',然后 $b = $a,$c = $a,最后 $a = 'junk',你在暗示 $b 和 $c 现在将等于 'junk' 吗?虽然我手头没有 PHP 环境,但这似乎相当疯狂。 - jahroy
如果a是指针并且您正在编写C程序(我猜我从未在PHP中使用过指针),我同意。 - jahroy
@jahroy:不,但是如果你设置 $b = &$a 那么它就会是真的。 - Madara's Ghost
@FelixKling: 现在好点了吗? - Madara's Ghost
嘿,我对措辞感到满意,但是没错,这样肯定更清晰 :) - Felix Kling
显示剩余2条评论

1

你已经回答了自己的问题。如果你想让myArray[0]等于bear,那么设置:

myArray[0] = "bear";

1
你可能没有理解问题的要点。OP问的是他是否可以在数组中存储引用,以便他不必像你那样显式地直接访问数组。有关更多信息,请参见https://dev59.com/AWPVa4cB1Zd3GeqP8sA8#10559622。 - jamesmortensen
我知道这一点,纯粹是指如果目标是更改存储在数组中的某个值,则需要通过数组索引器访问它。 - dougajmcdonald
通常在StackOverflow上,答案应该回答问题。否则,它们应该作为对问题的评论发布。考虑添加更多回答问题的信息,这将使您的帖子对社区更有价值。祝你好运! - jamesmortensen

1

即使您的数组保存了对象的引用,使变量引用完全不同的对象也不会更改数组的内容。

您的代码并没有修改变量a所引用的对象。它使变量a引用完全不同的对象。

就像您的JavaScript代码一样,以下Java代码也无法工作,因为像JavaScript一样,Java按值传递对象的引用:

  Integer intOne = new Integer(1);
  Integer intTwo = new Integer(2);

  Integer[] intArray = new Integer[2];
  intArray[0] = intOne;
  intArray[1] = intTwo;

  /* Make intTwo refer to a completely new object */

  intTwo = new Integer(45);

  System.out.println(intArray[1]);

  /* output = 2 */

在Java中,如果您更改变量引用的对象(而不是将新引用分配给变量),则会获得所需的行为。
例如:
  Thing thingOne = new Thing("funky");
  Thing thingTwo = new Thing("junky");

  Thing[] thingArray = new Thing [2];

  thingArray[0] = thingOne;
  thingArray[1] = thingTwo;

  /* Modify the object referenced by thingTwo */

  thingTwo.setName("Yippee");

  System.out.println(thingArray[1].getName());

  /* output = Yippee */

  class Thing
  {
      public Thing(String n) { name = n; }
      private String name;
      public String getName() { return name; }
      public void setName(String s) { name = s; }
  }

我知道你在这方面付出了很多努力,而且写得非常好,但问题是关于JavaScript的,问题标记为JavaScript而不是Java。然而,Java和JavaScript都是按值传递的,其中对象引用也是按值传递的。因此,在这个特定情况下,我认为你的答案和解释仍然适用。考虑添加一些JavaScript示例,以便更全面。 :) - jamesmortensen
谢谢。我知道这个问题是关于JavaScript的,但我想这可能有助于阐明一点。你提出了一个很好的观点,很容易添加一些JavaScript(或替换Java)。 - jahroy
我赞成添加。即使信息可能有些错位,我也不喜欢丢弃好的信息。还有一点,请务必查看关于Java和JavaScript是按值传递而不是按引用传递的文章。在你的答案中,这可能是你需要修复的唯一问题。祝你好运! - jamesmortensen
谢谢,我刚刚读了它...我会修复的。我想我是那些认为Java通过引用传递对象而不是按值传递这些引用的人之一。耶,我今天学到了东西!再次感谢。 - jahroy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接