我有一个JavaScript / ES6 class
,其成员名为x
,初始化为[1,2,3,4]
。
当我在一个名为y
的方法中声明一个新变量,并为其指定x
,然后更改x
中的值时,y
保持不变,表明y
是x
的副本。
如果我在同一方法中声明并将y
分配给名为z
的变量,则修改z
会更改y
,但不会更改x
。
这表明声明一个类级别数组(对象?)然后将其分配给方法内的变量复制该对象。这与C#等语言有很大不同。
为什么在JavaScript / ES6中以这种方式实现?
class Alpha {
constructor() {
this.x = [1, 2, 3, 4];
}
DoSomething() {
console.log('x is ' + this.x); // x is 1,2,3,4
let y = this.x;
this.x = [99, 99, 99, 99];
console.log('x is ' + this.x); // x is 99,99,99,99
console.log('y is ' + y); // y is 1,2,3,4 (?)
let z = y;
z[1] = 888;
console.log('x is ' + this.x); // x is 99,99,99,99
console.log('y is ' + y); // y is 1,888,3,4
console.log('z is ' + z); // z is 1,888,3,4
}
}
let thing = new Alpha();
thing.DoSomething()
let y = this.x;
this.x = [99, 99, 99, 99];
y现在指向[1,2,3,4] .... this.x现在指向一个新数组[99,99,99,99];
编辑
记录在案,这与ES6无关
编辑#2
y现在指向内存中包含数组[1,2,3,4]的位置,而this.x现在指向内存中包含数组的不同位置[99,99,99,99];
这个问题的核心是对内存分配的理解。
这是内存存储值的方式以及变量如何指向内存中的不同值。
Statement Value of x Value of y
+------------------------+---------------------+-------------------+
| let x = [1, 2, 3, 4]; | [1, 2, 3, 4] | |
| let y = x; | [1, 2, 3, 4] | [1, 2, 3, 4] |
| x = [99, 99, 99, 99]; | [99, 99, 99, 99] | [1, 2, 3, 4] |
+------------------------+---------------------+-------------------+
基本上,这两个变量包含/指向不同的值,因此一个变量中的修改不会“影响另一个”。
它与类或类方法无关,并且一直存在于javascript中。
let tab_origin = [ "aa", "bb", "cc" ];
let same_tab = tab_origin;
这使得tab_origin
和same_tab
指向数组的相同地址。换句话说,你只有一个数组和两个不同的变量来访问它。
same_tab[0] = "zz";
console.log( tab_origin[0] ); // => "zz"
小心这个功能:
function myfunction(inTab)
{
inTab[1] = "ff"
}
myfunction(tab_origin);
console.log( tab_origin[1] ); // => "ff" !!
所以,如果你想要你的数组的副本你必须这样做:
let other_tab = Object.assign( [], tab_origin );
顾名思义这个方法允许分配一个新的对象
other_tab[2] = "xy";
console.log( tab_origin[2] ); // => "cc" - unchanged :)
console.log( other_tab[2] ); // => "xy"
let tab_origin = [ "aa", "bb", "cc" ];
let same_tab = tab_origin;
same_tab[0] = "zz";
console.log( 'tab_origin[0]', tab_origin[0] ); // => "zz"
function myfunction(inTab)
{
inTab[1] = "ff";
}
myfunction(tab_origin);
console.log( 'tab_origin[1]', tab_origin[1] ); // => "ff"
let other_tab = Object.assign( [], tab_origin );
other_tab[2] = "xy";
console.log( 'tab_origin[2]', tab_origin[2] ); // => "cc"
console.log( 'other_tab[0]', other_tab[2] ); // => "xy"