原始类型(Number,String 等)按值传递,但是对象是未知的,因为它们可以是值传递(如果我们认为持有对象的变量实际上是对象的引用)并且通过引用传递(当我们认为对象的变量保存对象本身时)。
虽然最后并不重要,但我想知道提交传递约定的参数的正确方法是什么。是否有 JavaScript 规范的摘录,它定义了与此相关的语义?
它在 Javascript 中很有趣。考虑这个例子:
function changeStuff(a, b, c)
{
a = a * 10;
b.item = "changed";
c = {item: "changed"};
}
var num = 10;
var obj1 = {item: "unchanged"};
var obj2 = {item: "unchanged"};
changeStuff(num, obj1, obj2);
console.log(num);
console.log(obj1.item);
console.log(obj2.item);
这会产生输出:
10
changed
unchanged
obj1.item
对函数外部的obj1
没有影响。 num
将为100
, obj2.item
将显示为"changed"
。 相反,情况是传入的项目是按值传递的。但是通过值传递的项本身就是一个引用。从技术上讲,这称为分享呼叫 。
实际上,这意味着如果您更改参数本身(与num
和obj2
),则不会影响输入参数的项目。但是如果你更改参数的INTERNALS ,它将传播回来(与obj1
)。
它总是按值传递,但对于对象,变量的值是引用。因此,当您传递一个对象并更改其成员时 ,这些更改将在该函数之外保留。这使它看起来像通过引用传递。但是,如果您实际更改了对象变量的值,您将看到更改不会持续存在,从而证明它确实是通过值传递的。
例:
function changeObject(x) {
x = {member:"bar"};
alert("in changeObject: " + x.member);
}
function changeMember(x) {
x.member = "bar";
alert("in changeMember: " + x.member);
}
var x = {member:"foo"};
alert("before changeObject: " + x.member);
changeObject(x);
alert("after changeObject: " + x.member); /* change did not persist */
alert("before changeMember: " + x.member);
changeMember(x);
alert("after changeMember: " + x.member); /* change persists */
输出:
before changeObject: foo
in changeObject: bar
after changeObject: foo
before changeMember: foo
in changeMember: bar
after changeMember: bar
变量不 “保持” 对象,它保存一个引用。您可以将该引用分配给另一个变量,现在它们都引用同一个对象。它总是按值传递(即使该值是参考值......)。
没有办法改变作为参数传递的变量所持有的值,如果 JS 支持通过引用传递,这将是可能的。