不了解基本的JavaScript执行流程

时间:2018-03-10 21:33:11

标签: javascript arrays variable-assignment

我的基本理解是JavaScript从上到下运行,在调用函数时返回函数,但在调用函数后继续执行下一行代码。

当我将此代码视为示例时,这是有道理的:

var a = 5;
var b = a;
a = 2;
console.log(b);
// My expected output 5, works as expected

我看到这个时迷路了:

var a = [5];
var b = a;
a.push(2);
console.log(b);
// My expected output [5], instead returns [5,2]

如果我将var b的值分配给它为5,为什么当2没有被推到a直到NEXT线时,b的值变为[5,2]?

我在这里显然缺少一些基本的基础知识。

3 个答案:

答案 0 :(得分:0)

你正在将2推到数组上,因为b指向a,console.log(b)的输出输出[5,2]而不是5。

答案 1 :(得分:0)

您看到[5, 2]的原因是:

  • b是对a
  • 的引用
  • 因此,当您修改a时,b会将这些更改反映为b指向a

简而言之,JavaScript中的复杂对象(即数组和对象)通过引用传递,而原语按值传递:

  • 这主要是性能优势。例如,想想拥有一个大型物体 - 每次你传递那个物体时,你最终会复制它,这可能不是一个好主意
  • 幸运的是,有一些方法可以执行深层对象克隆。以下是此资源:How do I correctly clone a JavaScript object?
  • 要记住的事情:只有当对象没有更多的活动引用时,分配给该对象的内存块才会在垃圾回收期间被回收(即,检查What is JavaScript garbage collection?

以下是与您的问题相关的一个很好的讨论:Is JavaScript a pass-by-reference or pass-by-value language?

希望它有所帮助。

答案 2 :(得分:0)

ab仍然包含相同的数组。

问题是a.push(2);没有为a分配新值;相反,它修改了a中存储的实际数组。由于b包含相同的数组,因此ab都可以看到对它的任何修改。

这个问题不会出现在所谓的"原语"数字类型,因为数字没有可变结构。您无法将2修改为突然5011,但您可以修改数组以使其具有不同的大小和不同的内容。