这两段代码的输出不同是因为对象引用和对象赋值的区别。
第一段代码:
var controlPoints = [{ x: 100, y: 200 }];
let obj = null;controlPoints.forEach(item => {obj = item;
});obj.x = 300;
obj.y = 500;controlPoints[0];
第二段代码:
var controlPoints = [{ x: 100, y: 200 }];
let obj = null;controlPoints.forEach(item => {obj = item;
});obj = { x: 300, y: 500 };controlPoints[0];
详细解释
-
第一段代码的执行过程:
- 初始化
controlPoints
为包含一个对象的数组。 - 初始化
obj
为null
。 - 使用
forEach
遍历controlPoints
数组,obj
被设置为数组中唯一对象的引用。 - 通过
obj.x = 300
和obj.y = 500
修改了obj
所引用的对象的属性。 - 因为
obj
引用的是controlPoints
数组中的对象,所以修改obj
的属性也会修改controlPoints
数组中的对象。
因此,
controlPoints[0]
会变成{ x: 300, y: 500 }
。 - 初始化
-
第二段代码的执行过程:
- 初始化
controlPoints
为包含一个对象的数组。 - 初始化
obj
为null
。 - 使用
forEach
遍历controlPoints
数组,obj
被设置为数组中唯一对象的引用。 - 通过
obj = { x: 300, y: 500 }
,obj
被赋值为一个新的对象{ x: 300, y: 500 }
。 - 这个赋值操作不会影响
controlPoints
数组中的对象,因为obj
现在指向的是一个新的对象。
因此,
controlPoints[0]
依然是{ x: 100, y: 200 }
。 - 初始化
对象引用和对象赋值的区别
-
对象引用:当你将一个对象赋值给另一个变量时,实际上是将该对象的引用赋值给了新变量。两个变量指向同一个对象,通过其中任意一个变量修改对象的属性,另一个变量也会看到变化。
例如:
let a = { x: 1, y: 2 }; let b = a; // b 是对 a 所引用对象的引用 b.x = 3; // 现在 a.x 也是 3
-
对象赋值:当你将一个新的对象赋值给一个变量时,这个变量开始引用新的对象,之前的引用关系被打破。
例如:
let a = { x: 1, y: 2 }; let b = a; // b 是对 a 所引用对象的引用 b = { x: 3, y: 4 }; // 现在 b 指向一个新的对象 // a 还是 { x: 1, y: 2 }
总结
- 第一段代码修改了
controlPoints
数组中的对象,因为obj
是对该对象的引用。 - 第二段代码没有修改
controlPoints
数组中的对象,因为obj
被赋值为一个新的对象,从而失去了对原对象的引用。
所以,输出不同是因为对象引用和对象赋值的区别导致的。