通过引用传递 JavaScript 的原始变量

9

我正在尝试通过引用传递基本变量。

var foo = 2;
function inc (arg) {
    arg++
}
inc(foo) //won't increment foo

上述代码在 JavaScript 中不起作用,因为基本数据类型(如数字)是按值传递的,而对象则是按引用传递的。为了将基本数据类型按引用传递,我们需要将它们声明为对象:
var foo = new Number(2)
function inc (arg) {
    arg++
}
inc(foo) //increments foo

这似乎是一种不太正规的解决方法,可能会影响执行速度。在其他面向对象编程语言中,我们可以将“指针”或“引用”传递给函数。在JS中有类似的东西吗?谢谢!


你在问什么?在 JavaScript 中,原始类型不存在按引用传递。 - XCS
真正的问题是作用域。你应该了解JS的工作原理。一个简单的链接:http://www.w3schools.com/js/js_scope.asp - manuerumx
更好的链接:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Closures - manuerumx
在其他面向对象的编程语言中,我们可以将“指针”或“引用”传递给函数,但并非所有语言都支持此操作。例如,Java甚至没有真正的函数(不过Java 8对类有所改进)。问题是,为什么想要能够通过引用传递?这有什么好处呢? - VLAZ
1个回答

12

在JavaScript中,你无法通过引用传递基本类型数据 - 而且这个“解决方法”的示例也不起作用。原因如下:

var foo = new Number(2)  // line 1
function inc (arg) {     // line 2
    arg++                // line 3
}

第一行将foo设置为一个数字对象包装器,其基本值为2。

第二行定义了一个形式参数arg,它在函数作用域中具有自己的存储位置,用于保存参数值的副本。

第三行增加了实际参数值(Number对象引用的副本)所存储的位置——在为arg分配的内存中,而不是foo。如果您在调用后检查foo的基本值,则仍然为2。

实际上,您可以传递对具有递增foo属性的对象的引用:

var obj = {}
obj.foo = 2
function incFoo (obj) {
    obj.foo++
}
incFoo()  // obj.foo now 3

实际上,在ECMA脚本中没有可用于引用原始值的地址指针。


1
对象几乎是按引用传递。更确切地说,它是按引用副本传递。但这只是一个很小的细节 - 这意味着如果您在函数中接受参数obj,则 obj = null 不会清除实际对象。除此之外 - 您是正确的,特别是关于 new Number 不是解决方法。 - VLAZ
1
@vlaz 完全同意,但也许可以用不同的方式来考虑。我早就放弃了“除了对象以外,所有参数都是按值传递(复制操作)而对象是按引用传递”的说法,转而采用“所有参数都是按值传递,包括对象数据类型,因为对象数据类型包含对存储在其他地方的对象数据的引用。”;-) - traktor

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