如果 b = a,为什么在下一行重新定义 a 后 b 会发生变化?
If b = a, why does b change after I redefine a in the next line?
谁能解释一下这两种情况的区别?也就是说,为什么 b 在第一个中没有被重新定义,但在第二个中被重新定义了?
a = [0,1,2,3,4]
b = a //b = [0,1,2,3,4]
a = 4
console.log(b) //b is still [0,1,2,3,4]
//redefining a AFTER saying b = a will NOT change b
/
a = [0,1,2,3,4]
b = a //b = [0,1,2,3,4]
for ( i = 0; i < a.length; i++){
a[a.length - (i + 1)] = b[i]
} //I though this loop would redefine a as b in reverse. But this happens:
console.log(a) //both a and b have changed to [0,1,2,1,0]
console.log(b) //I don't understand why b changed at all, since a is being redefined
//AFTER I saved b as [0,1,2,3,4] and the = sign is supposed to just
//assign the value on the right to the value on the left
在第一种情况下,您将单个数组的引用存储到两个变量中 - a
和 b
。然后您更改了 a
,它删除了引用,现在包含 4
。在此之后你只有变量 b
引用数组和 你只能通过 b
.
更改该数组的项目
在第二种情况下,您再次在变量 a
和 b
中对单个数组进行了两次引用。但是当你做一些工作并更改一项 a[a.length - (i + 1)] = b[i]
时,此语句只是通过引用并更改单个数组对象中的一项,因为 b
也引用相同的数组,相同的更改是通过变量可见 b
.
所以这个语句 a[a.length - (i + 1)] = b[i]
获取 b[i]
的项目并将其分配给 a[a.length - (i + 1)]
,但这也等同于语句 b[b.length - (i + 1)]
。
简而言之,您在 a
和 b
中有相同的引用,如果您通过 a
更改数组,b
也会更改,因为它们引用同一个数组。
如果要更改第一个数组而不影响第二个数组,则需要创建两个单独的数组。您可以通过 slice
函数或数组扩展运算符 ([...a]
) 来完成,或者只需调用 a.reverse
到 return 反转数组。
const a = [0,1,2,3,4];
const b = a.slice(); // splice returns a new array
for(let i = b.length - 1; i >= 0; i--) {
a[a.length - i - 1] = b[i];
}
console.log(a);
console.log(b);
或者直接调用reverse
函数
let a = [0,1,2,3,4];
let b = [...a];
a.reverse();
console.log(a);
console.log(b);
这样理解
案例一
a = [0,1,2,3,4]
这相当于
Ref#1 = [0,1,2,3,4]
a = Ref#1
当您执行 b = a
时,相当于
b = Ref#1
和a = 4
等同于
Ref#2 = 4
a = ValOfRef#2
现在 b 仍然保持 Ref#1
,这就是为什么它仍然是 [0,1,2,3,4]
。请注意原始数据类型,如 Number
在您的情况下是 value
类型,而 Objects/Arrays
是引用类型。
案例二
在这种情况下,您正在遍历 Ref#1
并同时修改它,因为 a
和 b
都持有 Ref#1
,这就是为什么您得到意想不到的结果。为了获得预期的结果,您必须打破 a
和 b
的引用。在您的情况下,最简单的方法是使用 JSON.parse(JSON.strigify())
。见下文
a = [0, 1, 2, 3, 4]
b = JSON.parse(JSON.stringify(a));
for (i = 0; i < a.length; i++) {
a[a.length - (i + 1)] = b[i];
}
console.log(a);
console.log(b);
谁能解释一下这两种情况的区别?也就是说,为什么 b 在第一个中没有被重新定义,但在第二个中被重新定义了?
a = [0,1,2,3,4]
b = a //b = [0,1,2,3,4]
a = 4
console.log(b) //b is still [0,1,2,3,4]
//redefining a AFTER saying b = a will NOT change b
/
a = [0,1,2,3,4]
b = a //b = [0,1,2,3,4]
for ( i = 0; i < a.length; i++){
a[a.length - (i + 1)] = b[i]
} //I though this loop would redefine a as b in reverse. But this happens:
console.log(a) //both a and b have changed to [0,1,2,1,0]
console.log(b) //I don't understand why b changed at all, since a is being redefined
//AFTER I saved b as [0,1,2,3,4] and the = sign is supposed to just
//assign the value on the right to the value on the left
在第一种情况下,您将单个数组的引用存储到两个变量中 - a
和 b
。然后您更改了 a
,它删除了引用,现在包含 4
。在此之后你只有变量 b
引用数组和 你只能通过 b
.
在第二种情况下,您再次在变量 a
和 b
中对单个数组进行了两次引用。但是当你做一些工作并更改一项 a[a.length - (i + 1)] = b[i]
时,此语句只是通过引用并更改单个数组对象中的一项,因为 b
也引用相同的数组,相同的更改是通过变量可见 b
.
所以这个语句 a[a.length - (i + 1)] = b[i]
获取 b[i]
的项目并将其分配给 a[a.length - (i + 1)]
,但这也等同于语句 b[b.length - (i + 1)]
。
简而言之,您在 a
和 b
中有相同的引用,如果您通过 a
更改数组,b
也会更改,因为它们引用同一个数组。
如果要更改第一个数组而不影响第二个数组,则需要创建两个单独的数组。您可以通过 slice
函数或数组扩展运算符 ([...a]
) 来完成,或者只需调用 a.reverse
到 return 反转数组。
const a = [0,1,2,3,4];
const b = a.slice(); // splice returns a new array
for(let i = b.length - 1; i >= 0; i--) {
a[a.length - i - 1] = b[i];
}
console.log(a);
console.log(b);
或者直接调用reverse
函数
let a = [0,1,2,3,4];
let b = [...a];
a.reverse();
console.log(a);
console.log(b);
这样理解
案例一
a = [0,1,2,3,4]
这相当于
Ref#1 = [0,1,2,3,4]
a = Ref#1
当您执行 b = a
时,相当于
b = Ref#1
和a = 4
等同于
Ref#2 = 4
a = ValOfRef#2
现在 b 仍然保持 Ref#1
,这就是为什么它仍然是 [0,1,2,3,4]
。请注意原始数据类型,如 Number
在您的情况下是 value
类型,而 Objects/Arrays
是引用类型。
案例二
在这种情况下,您正在遍历 Ref#1
并同时修改它,因为 a
和 b
都持有 Ref#1
,这就是为什么您得到意想不到的结果。为了获得预期的结果,您必须打破 a
和 b
的引用。在您的情况下,最简单的方法是使用 JSON.parse(JSON.strigify())
。见下文
a = [0, 1, 2, 3, 4]
b = JSON.parse(JSON.stringify(a));
for (i = 0; i < a.length; i++) {
a[a.length - (i + 1)] = b[i];
}
console.log(a);
console.log(b);