TypeScript 结构体赋值后不相等的原因 | 南锋

南锋

南奔万里空,脱死锋镝余

TypeScript 结构体赋值后不相等的原因

在 TypeScript 中,如果你遇到 结构体A = 结构体B 之后,发现 结构体A 不等于 结构体B,有几种可能原因。

1. 引用和复制的区别

在 JavaScript 和 TypeScript 中,非原始数据类型(例如对象和数组)是通过引用传递的,而不是值传递。也就是说,如果你直接使用 =结构体B 赋值给 结构体A,实际上 结构体A结构体B 引用的是同一个内存地址。

但是,如果你修改了其中一个结构体的属性,另一个结构体的相应属性也会改变,这说明它们共享同一个引用。如果你期望两个结构体独立且相等,你需要做一个“深拷贝”。

例如:

1
2
3
4
5
6
7
8
let structA = { a: 1, b: 2 };
let structB = { a: 1, b: 2 };
structA = structB;

console.log(structA === structB); // true

structA.a = 3;
console.log(structB.a); // 输出 3,因为两者引用同一个对象

在这种情况下,如果你修改了 structA 的属性,structB 的属性也会改变,因为它们是同一个对象的引用。

2. 浅拷贝 vs 深拷贝

可能你在进行赋值的时候只进行了“浅拷贝”,没有进行“深拷贝”。浅拷贝只会拷贝对象的第一层,如果对象的属性也是对象,那么它们依旧引用的是同一个内存地址。

如果要进行深拷贝,你可以使用一些工具,例如:

  • JSON.parse(JSON.stringify(structB)):适用于简单对象,但不支持函数、循环引用等复杂对象。
  • 使用 Lodash 的 cloneDeep() 方法:
    1
    2
    import _ from 'lodash';
    let structA = _.cloneDeep(structB);
  • 使用自定义递归方法进行深拷贝。

3. 对象比较

即使 structAstructB 的内容相同,在进行 ===== 比较时,它们还是会被认为是不相等的,因为它们指向的是不同的引用。

例如:

1
2
3
4
let structA = { a: 1, b: 2 };
let structB = { a: 1, b: 2 };

console.log(structA === structB); // false

在这个例子中,尽管 structAstructB 的内容完全相同,它们的内存引用是不同的,因此比较时结果为 false

如果你需要比较两个对象的内容是否相同,可以写一个自定义的比较函数,或者使用像 Lodash 这样的工具库中的 isEqual() 函数:

1
2
import _ from 'lodash';
console.log(_.isEqual(structA, structB)); // true

4. 原型链的影响

如果结构体是通过类实例化的对象,可能它们的原型链会有所不同,导致 === 比较时它们不相等。特别是当你使用了对象继承、原型修改等操作时,需要注意对象的原型链关系。

总结

如果 结构体A = 结构体B 后,发现 结构体A 不等于 结构体B,可能原因包括:

  1. 你在比较时使用了引用比较,而不是内容比较。
  2. 你使用的是浅拷贝,导致对象的嵌套属性指向了不同的引用。
  3. 你需要使用深拷贝来保证两个结构体独立,但内容相同。
  4. 如果需要内容相等比较,可以使用 Lodash 的 _.isEqual() 等工具方法。
+