这是几乎所有现代命令式编程语言的正常行为,这些命令式语言具有不变的原语和可变对象,例如Java,Python,Javascript等。我将使用Javascript作为示例,但是如果您不希望使用Javascript,那么代码足够简单,无论如何您都可以理解其解释。
请考虑以下代码,该代码声明一个变量并调用一个函数:
function foo(x) {
x = 5;
}
var y = 2;
foo(y);
console.log(y); // outputs number 2
函数中的变量x
从y
获取其值,但它是存储在内存中不同位置的另一个变量。因此,当函数将数字5分配给x
时,数字5也被不分配给y
; x
中的更改不在函数外部“可见”。
现在考虑这段代码,本质上是相同的,只是用一个对象而不是一个数字:
function bar(x) {
x = { a: 3,b: 4 };
}
var y = { a: 1,b: 2 };
bar(y);
console.log(y); // outputs { a: 1,b: 2 }
同样,x
从y
(是对对象的引用)获取其值,但是为x
分配新引用不会更改哪个引用{{1} }成立是因为它们存储在不同的存储位置。
现在是最后一个示例:
y
这一次函数function baz(x) {
x.a = 3;
x.b = 4;
}
var y = { a: 1,b: 2 };
baz(y);
console.log(y); // outputs { a: 3,b: 4 }
确实会更改结果,因为baz
持有对对象的引用,并且在调用函数时,y
持有对同一对象的引用(不是对象的副本),因此对其属性的分配 在函数外部是“可见的”。
如果您觉得所有这些都简单明了,则可以忽略该段落;这只是在说明他们在书中使用的语言具有这些行为。该段的目的是阐明其语言的语义,因为并非所有语言的所有功能都以这种方式表现。
例如,在C ++中,可以这样编写x
和foo
,以使它们 可以“从远处”改变y的值。或者,在对象不可变的功能编程语言中,bar
不会更改对象baz
,它会创建具有不同属性的新对象,而不会在函数外部可见。
因此,书中的这一段对于可能更熟悉函数参数的其他语义的读者来说是一个有用的澄清。
本文链接:https://www.f2er.com/3126951.html