【问题标题】:Javascript - Pass by Reference in an Object using Extend (underscore.js library)Javascript - 使用 Extend(underscore.js 库)在对象中通过引用传递
【发布时间】:2018-12-15 12:35:55
【问题描述】:

在 Javascript 中,当我使用 underscore.js 库中的扩展函数时...有人可以从概念上/视觉上向我描述后端在内存方面发生的事情 - 以这个例子为例:

var obj = {hello: [2]};
var obj2 = {hola: [4]};
_.extend(obj, obj2)
obj2.hola = 5;
console.log(obj) // hola still has a value of `[4]`

我的问题是,如果我 console.log(obj),出于某种原因,hola 的值仍然是 [4]。我完全认为我会得到值 5(通过引用传递)......

对于上面的例子,这是我脑海中视觉/概念上发生的事情:

  1. extend函数将密钥hola深度复制到obj中:

    obj = {hello: [2], hola: TBD} ]btw - obj 是否只为这个对象存储一个内存地址?

  2. 然后我怀疑 hola 将内存地址存储为 [4] 的值(所以此时我怀疑 obj 会是

    obj = {你好:[2],你好:#0x93490234}

这就是为什么我完全期望在 obj 下看到 5。你能告诉我我上面的可视化有什么问题吗?

最后,通过解释,你能指出上面的例子与下面的例子有什么不同吗(我理解下面的例子是如何/为什么工作的——只是不是上面的例子,想听听为什么下面的例子有效,以上没有)。

var obj2 = {hola: [4]};
var obj = obj2;
obj2.hola = 5; //console.log(obj) will say that hola equals 5

【问题讨论】:

  • JavaScript 中的所有参数始终按值传递。 Read this 解释一下。
  • 感谢@ScottMarcus - 我阅读了您链接中的解释,但对我没有太大帮助。我的示例中没有函数/没有参数。我不确定它与我的问题有何关系 - 任何指导都将不胜感激......
  • 您的示例中确实有一个函数.extend(),并且您正在向它传递参数。这些参数是按值传递的。
  • _.extend 复制 obj2 拥有当时的属性到obj。更改obj2 之后obj 没有影响。
  • 我只是想帮助你理解在 JavaScript 中没有通过引用传递这样的东西。

标签: javascript pass-by-reference


【解决方案1】:

也许这会有所帮助:

让我们首先区分两个概念:绑定。值是一段数据,如字符串、数字、布尔值、对象等。每个值都存储在内存中并有一个地址。

绑定就像一个包含地址的容器或标签。

  • 在为绑定分配值时,我们正在分配值的地址
  • 访问绑定时,我们会获取存储在该地址的值

例子:

var a = 42;

a 是一个绑定,42 是一个值。假设42 存储在内存中的0x1,那么a 确实保存了地址0x1

当我们试图读取值时,例如

console.log(a);

我们需要查看地址0x1 以获取实际值。

现在当我们“将一个绑定分配给另一个绑定”时会发生什么,即bar = foo

var foo = 42; // 0x2
var bar = foo;

42 存储在0x2。所以foo 持有地址0x2。当我们将绑定分配给另一个绑定时,我们只需复制绑定所持有的地址。所以在var bar = foo;之后,foobar都持有地址0x2。 如果我为foo 分配一个新值,例如

foo = 21;

然后我让foo 持有一个新地址(例如0x3)。

这不会改变bar 持有的地址。

同样适用于对象属性。


可变值

现在您可能想知道“为什么foobar 在以下示例中都发生了变化:

var foo = [42];
var bar = foo;
foo.push(21);
// bar also has [42, 21]

假设[42] 存储在内存位置0x4

以下是它与上一个示例的不同之处:

我们没有为 foo 分配新值。

相反,我们引用数组(地址0x4通过foo变异它。可变值是可以就地更改的值,即该内存位置的位可以更改。

在调用foo.push 之后,foo 仍然拥有地址0x4bar 也是如此。

【讨论】:

    猜你喜欢
    • 2012-07-16
    • 2015-09-19
    • 1970-01-01
    • 2020-10-12
    • 2015-06-18
    • 2017-09-11
    • 2011-03-18
    • 2013-08-11
    相关资源
    最近更新 更多