在 TypeScript 中,将一个接口对象赋值给另一个变量时,实际上是传递引用而不是进行数据拷贝。也就是说,两个变量都引用同一个对象,因此对其中一个变量进行修改会影响到另一个变量。
示例
假设我们有一个接口 FontSizeEntity
:
interface FontSizeEntity {
size: number;
unit: string;
}
const fontSize: FontSizeEntity = {
size: 16,
unit: 'px'
};
// 将 fontSize 赋值给另一个变量
const anotherFontSize = fontSize;
console.log(anotherFontSize); // { size: 16, unit: 'px' }
// 修改 anotherFontSize 会影响 fontSize,因为它们引用的是同一个对象
anotherFontSize.size = 20;
console.log(fontSize); // { size: 20, unit: 'px' }
console.log(anotherFontSize); // { size: 20, unit: 'px' }
解释
-
传引用: 当我们将
fontSize
赋值给anotherFontSize
时,anotherFontSize
只是对fontSize
所引用的同一个对象的引用。因此,对anotherFontSize
的任何修改都会反映在fontSize
上,反之亦然。 -
数据拷贝: 如果你希望创建一个新对象,并且与原对象相互独立,则需要进行数据拷贝。这可以通过对象展开操作符(spread operator)或其他方法来实现。
数据拷贝示例
如果你希望赋值时进行数据拷贝,可以使用对象展开操作符(spread operator):
interface FontSizeEntity {
size: number;
unit: string;
}
const fontSize: FontSizeEntity = {
size: 16,
unit: 'px'
};
// 创建一个新的对象,进行浅拷贝
const anotherFontSize = { ...fontSize };
console.log(anotherFontSize); // { size: 16, unit: 'px' }
// 修改 anotherFontSize 不会影响 fontSize,因为它们是两个独立的对象
anotherFontSize.size = 20;
console.log(fontSize); // { size: 16, unit: 'px' }
console.log(anotherFontSize); // { size: 20, unit: 'px' }
深拷贝
对于嵌套对象的深拷贝,可以使用 JSON.parse
和 JSON.stringify
或者 lodash
库中的 cloneDeep
方法:
import _ from 'lodash';
interface FontSizeEntity {
size: number;
unit: string;
details?: {
fontWeight: string;
};
}
const fontSize: FontSizeEntity = {
size: 16,
unit: 'px',
details: {
fontWeight: 'bold'
}
};
// 使用 lodash 的 cloneDeep 方法进行深拷贝
const anotherFontSize = _.cloneDeep(fontSize);
console.log(anotherFontSize); // { size: 16, unit: 'px', details: { fontWeight: 'bold' } }
// 修改 anotherFontSize 的嵌套属性不会影响 fontSize,因为它们是两个独立的对象
anotherFontSize.details!.fontWeight = 'normal';
console.log(fontSize.details); // { fontWeight: 'bold' }
console.log(anotherFontSize.details); // { fontWeight: 'normal' }
总结
- 传引用: 默认情况下,赋值操作是传递引用。
- 浅拷贝: 使用对象展开操作符
{ ...obj }
可以进行浅拷贝。 - 深拷贝: 使用
JSON.parse(JSON.stringify(obj))
或lodash
的cloneDeep
方法进行深拷贝。