JavaScript 中的 Tuples 和 Records 是什么?
不变性是我们谈论函数式编程时经常出现的一个常用术语。 这是因为它是其核心原则之一。 当我们谈论不可变对象时,我们只是意味着一旦声明了一个变量,它的值就不能在以后进行更改。 例如:
const presents = ['????', '????', '????', '????', '????'];// --- 可变解决方案 ---
// 我们略过 ????
// presents 将等价于 ['????', '????', '????', '????'];
presents.shift();
// --- 不可变的解决方案 ---
// newPresents 相当于 ???? ???? ???? ????
// presents 依然为 ['????', '????', '????', '????', '????'];
const newPresents = presents.slice(1);
第一个解决方案改变了数组,而第二个解决方案创建了一个新的并保持原始数组不变。 在 JavaScript 中,我们没有真正的不可变对象,所以我们要么需要变通方法来实现安全,要么更糟糕的是,我们必须相信人们不会改变这些值。
现在有一个新的 ECMAScript 提案——目前处于第 2 阶段,因此这些实现可以改变——将引入两种新的不可变数据类型:Tuples和 Records。
Tuples(元组)
Tuples 和 Records 都具有相同的语法。 它们可以通过在对象和数组前面使用 #
前缀来定义,如下所示:
// 这是一个正常的数组const arr = [];
// 这是一个 tuple
const tuple = #[];
使用 Tuples 时,需要注意一些规则:
- 数组中不能有空洞,例如:[1, ,2] 是不允许的;
- 它们只能包含原语或其他 Tuples 和 Records;
- 支持类似于 Arrays 的实例方法,但有一些变化;
例如,改变数组的操作被替换为返回新数组的新操作。 因此,例如:没有 push,我们可以使用 push 来返回一个带有推送值的新元组,或者使用 with 来更改给定索引处的值:
const tuple = #['????', '????', '????'];// 都返回一个新元组
tuple.pushed('????'); // 返回 #['????', '????', '????', '????'];
tuple.with(0, '????'); // 返回 #['????', '????', '????']
我们还可以使用 Tuple.from() 从现有数组创建元组:
Tuple.from(['????', '????', '????']);// 同样,我们可以将元组转换为普通数组:
Array.from(tuple);
当然,它们是不可变的,如果尝试更改它们的值或使用非原始值,它们会抛出错误:
const tuples = #['????', '????', '????'];// TypeError: Callback to Tuple.prototype.map may only return primitives, Records or Tuples
tuples.map(tuple =>newButton(tuple));
Records 记录
就像元组一样,记录也用哈希表示:
// 这是一个常规对象const obj = { ... };
// 这是一个记录
const record = #{
tuple: #['????', '????', '????'] // Records 也会包含 元组(Tuples)
};
处理记录时,我们还需要牢记一些规则:
- 不能在记录中使用
__proto__
标识符 - 方法也是不允许的。 就像元组一样,它们只能包含原语。
要创建新记录,我们还可以选择在使用元组时使用 Record
或 Record.fromEntries
:
const record = Record({mushroom: '????',
tomato: '????',
carrot: '????'
});
// 或者
const record = Record.fromEntries(#['????', '????', '????']);
而且由于它们是新的数据类型,因此在使用 typeof
运算符时会返回“record”:
typeof #{ ... } // 返回 "record"typeof #[ ... ] // 返回 "tuple"
总结
除了上面提到的示例之外,我们可以在函数或循环中同时使用记录和元组,就像我们通常使用常规对象一样。
如果你现在想要不可变,最简单的方法是使用 Immutable-js。 还可以使用 Object.freeze 实现部分不变性,但是,它只会冻结直接子级。 因此,我们仍然可以更改深度嵌套的属性:
const obj = Object.freeze({a: 1,
b: {
c: 2
}
});
// ✅ Won't work
obj.a = 10;
// ❌ Will be changed to 20
obj.b.c = 20;
当然,你也可以通过 plugin-syntax-record-and-tuple
插件将它与 Babel 一起使用。
大家是否已经使用过元组(Tuples)和记录(Records)? 欢迎大家在下面留言一起来讨论!
本文转载自:迹忆客(https://www.jiyik.com)
以上是 JavaScript 中的 Tuples 和 Records 是什么? 的全部内容, 来源链接: utcz.com/z/290315.html