在Javascript中将对象作为参数传递给函数

3

在C/C++中,我们知道我们有指向对象和数组的指针,因此它们可以作为函数参数传递,而不需要克隆这些对象和数组。在Javascript中没有这样的选项,因此我们只使用对象变量。

这是一个好的做法吗?

function setWhite(obj){
  obj.color = "white";
}

var shirt = {
  color: "red",
  size: "L"
}

setWhite(shirt);

console.log(shirt);


1
“但这样做是否可以?”它不会抛出错误,所以答案是“可以”。“这是好的实践吗?”这取决于情况。很多时候,改变对象导致不必要的复杂性。然而,在很多时候,这样做是可以接受的,因为它使事情变得简单。所以很明显......对此没有明确的答案。 - VLAZ
作为一个侧记,我认为你想说的是“传递对象”,而不是“解析对象”。解析是指拆分和理解数据。阅读并理解它。传递是你用来将数据传递给函数的术语。 - Jake T.
1
@JakeT.,已经进行了更正。 - João Pimentel Ferreira
1
@JoãoPimentelFerreira 在问题正文中漏掉了一个。指出这个小问题可能有点挑剔,但是编译器也非常挑剔,哈哈。而且没有正确的单词很难查找问题。 - Jake T.
@JoãoPimentelFerreira,但这种行为从JS开始就一直存在。此外,我的重点是你的问题非常没有意义,因为这里没有客观标准。这种行为就是它本身 - 它可能被滥用,也可能被很好地利用。这有点像询问将数字相加是否是良好的实践。 - VLAZ
显示剩余3条评论
1个回答

4
是的。在JavaScript中,对象是通过引用传递的。因此,如果您在函数内更改对象的值,则会在函数外部将其更改回来。
但是,如果您像这样做,情况就不同了:
function setWhite(obj){
  obj = {
    color: "white",
    size: "M"
  }
}

var shirt = {
  color: "red",
  size: "L"
}

setWhite(shirt);

console.log(shirt); // shirt will remain red / L

请注意,我在setWhite()方法中重新赋值了obj,因此原始的obj对象将被该函数覆盖丢失。
这是一个重要的概念,如果你忽略了它可能会产生令人不安和意想不到的后果,会导致误操作改变本不应改变的对象值,只是为了暂时地操纵数据以实现其他目的。当您开始使用异步函数时,尤其需要牢记这一点。异步函数在后台运行,必须指定何时进行等待。如果您调用异步函数并期望它更改您的对象值,但没有等待它完成,当您在调用异步函数的代码段之后再使用该对象时,可能会发现您的对象还没有更新。
同样地,如果您调用异步函数,但没有等待它完成,然后又更改了传入的对象,当异步函数试图使用该对象的值时,它们可能与您在调用它时预期的值不同。

4
对象是通过引用传递的,甚至更简单地说,对象就是引用。 - Bergi
@Bergi更加技术上正确。我选择了这种语言,因为它是从C/C++中使用的术语,但如果这不是一个合适的选择,我不会对编辑感到冒犯。 - Jake T.
@JakeT. 谢谢;但是为什么在你的例子中“原始 obj 丢失”?我猜是因为函数内部创建了另一个 _新引用_。这正确吗?当您字面上键入{};时,将创建一个新引用。 - João Pimentel Ferreira
1
是的,在 setWhite() 中执行 obj = ... 时,它会忘记旧引用,并创建对新对象的引用。旧的 shirt 仍然存在,因为函数外部的变量仍然保留着引用。但是,当你在函数内分配时,外部变量不会受到影响。您必须分配给对象的属性才能更改它们。 - Jake T.
1
你还可以将一个函数属性添加到衬衫对象本身中。在 {} 中,添加一行 setWhite: () => { this.color = "white"; }。然后,如果你想将其更改为白色,就可以调用 shirt.setWhite()。你也可以像这样添加 setColor: (newColor) => { this.color = newColor } 属性,然后调用 shirt.setColor('white'); - Jake T.
1
@JoãoPimentelFerreira 这超出了你的问题范围,如果你正在学习基础知识,这可能会让你消化不良,但是如果你查看其他人的源代码,你会看到所有这些实现方法的某种组合,因此理解它们非常重要。 - Jake T.

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