神奇的 Javascript,谁能告诉我为什么

2021-05-05 14:08:42 +08:00
 zero3412
let data = [
{x:0, y:1},
{x:2, y:3},
];

let A = data[0];
let B = data[1];

A.x = B.x;
A.y = B.y;

console.log(data, A, B)

为什么 data[0].x == 2 ???
明明申请了变量 A,我只想改变变量 A,怎么连 data 的值都变了
这是什么原理,搞 PHP 的搞不明白啊
6765 次点击
所在节点    JavaScript
53 条回复
ShuoHui
2021-05-05 16:12:27 +08:00
不懂 php,pythoner 感觉没毛病啊……
Rache1
2021-05-05 16:42:04 +08:00
PHP 里面对象也是引用的,数组不是
darknoll
2021-05-05 16:47:45 +08:00
这不是最基础的东西?
charlie21
2021-05-05 16:55:39 +08:00
1

JAVASCRIPT
let arr1 = [1,2,3,4];
let arr2 = arr1;
arr2[0] = 99;
console.log(arr2); // [99,2,3,4]
console.log(arr1); // [99,2,3,4]

JAVASCRIPT
let arr1 = [1,2,3,4];
let arr2 = [...arr1];
arr2[0] = 99;
console.log(arr2); // [99,2,3,4]
console.log(arr1); // [1,2,3,4]

JAVASCRIPT
let d1 = { x: 1, y:2 };
let d2 = d1;
d2.x = 80;
console.log(d2); // { x: 80, y: 2 }
console.log(d1); // { x: 80, y: 2 }

JAVASCRIPT
let d1 = { x: 1, y:2 };
let d2 = {...d1};
d2.x = 80;
console.log(d2); // { x: 80, y: 2 }
console.log(d1); // { x: 1, y: 2 }

关键词 js spread operator

2

PHP
$arr1 = [1,2,3,4];
$arr2 = $arr1;
$arr2[0] = 99;
var_export($arr2); // [99,2,3,4]
var_export($arr1); // [1,2,3,4]

PHP
$arr1 = [1,2,3,4];
$arr2 = &$arr1;
$arr2[0] = 99;
var_export($arr2); // [99,2,3,4]
var_export($arr1); // [99,2,3,4]

3

C#
int[] arr1 = new int[]{1,2,3,4};
int[] arr2 = arr1;
arr2[0] = 99;
Console.WriteLine(String.Join(" ", arr2)); // 99 2 3 4
Console.WriteLine(String.Join(" ", arr1)); // 99 2 3 4

C#
using System.Collections.Generic;
List<int> list1 = new List<int>{1,2,3,4};
List<int> list2 = new List<int>(list1);
list2[0] = 99;
list2.ForEach(Console.WriteLine); // 99 2 3 4
list1.ForEach(Console.WriteLine); // 1 2 3 4

C#
using System.Collections.Generic;
List<int> list1 = new List<int>{1,2,3,4};
List<int> list2 = list1;
list2[0] = 99;
list2.ForEach(Console.WriteLine); // 99 2 3 4
list1.ForEach(Console.WriteLine); // 99 2 3 4
belin520
2021-05-05 17:15:21 +08:00
面试面基础还是很有必要的,即使是八股文
很多人即使自己不知道为什么,也不尝试去弄清楚为什么
OHyn
2021-05-05 17:23:15 +08:00
这个在 java 、c 里头也是一样的呀。。。传值和传引用嘛
iyaozhen
2021-05-05 19:39:41 +08:00
PHP 虽然说是传值,但实际也是引用。然后有个写死复制的机制,就是当发现要修改 A 时,是复制了一份。
省去了需要自己 copy 的问题,比较符合人的思维
WillBC
2021-05-05 22:03:59 +08:00
等你感受一下 deep clone
Nitroethane
2021-05-05 22:14:38 +08:00
@JerryCha data[0] 不一定传引用啊,得看 data 的数据类型,如果是 char* data[],那 data[0] 就传的是指针,如果是 char data[],data[0] 照样传值
anguiao
2021-05-05 22:38:50 +08:00
虽然 JS 确实很神奇,但是这个是常规操作。
Yvette
2021-05-06 04:51:24 +08:00
JS 里除了 primitive types 是 pass by value 之外,其余所有的都是 reference
xuanbg
2021-05-06 06:39:25 +08:00
因为
let A = data[0];
let B = data[1];

所以 data 的值变成 [
{x:2, y:3},
{x:2, y:3},
];
xuanbg
2021-05-06 06:40:16 +08:00
因为
let A = data[0];
let B = data[1];

A.x = B.x;
A.y = B.y;

所以 data 的值变成 [
{x:2, y:3},
{x:2, y:3},
];
Marszm
2021-05-06 08:46:20 +08:00
这种需要深拷贝.....PHP 这波属于非主流操作
oneisall8955
2021-05-06 08:49:41 +08:00
JAVA 的路过,要不是这样的结果才奇怪😳
yl14786922106
2021-05-06 09:00:52 +08:00
js 按值传递和 按引用传递的区别 let A = data[0] 时,A 只是一个指针 指向堆区的 data[0] : {x:0,y:1},所以改变 A.x 时改变的是 data[0]。
meloncc
2021-05-06 09:12:50 +08:00
这个问题与 Javascript 没有关系
gtanyin
2021-05-06 10:17:02 +08:00
果然学编程应该从 C 学起,不然连指针的概念都要惊讶半天
liuky
2021-05-06 10:57:20 +08:00
楼主高级黑
misaka19000
2021-05-06 10:59:55 +08:00
这是来黑 PHP 的吧

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/774968

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX