gpt4 book ai didi

javascript - 使用 javascript 原型(prototype)系统创建共享结构的不可变对象(immutable对象)是否有意义

转载 作者:搜寻专家 更新时间:2023-11-01 04:40:40 26 4
gpt4 key购买 nike

到目前为止,对于 Javascript 中的不变性似乎有两种相反的解决方案:

  • 不可变的.js
  • 无缝不可变

immutable.js 引入了自己的(浅层)不可变对象(immutable对象),这些对象与对象和数组的默认 javascript 协议(protocol)不兼容。

seamless-immutable 使用完全不可变的 POJO,没有任何魔法,但没有结构共享。

将两全其美结合起来会很棒。不可变原型(prototype)链/树能否成为合适的解决方案?

底层原型(prototype)机制给了希望:

var a = [1, 2, 3];
var b = Object.create(a);

b[0]; // 1
b.map(function (x) { return ++x; }); // 2, 3, 4

b.push(4, 5, 6); // initial assignment of b
a; // 1, 2, 3
b; // 1, 2, 3, 4, 5, 6

for (var i = 0; i < b.length; i++) {
console.log(b[i]);
} // 1, 2, 3, 4, 5, 6

a[1] = null; // prototype mutation
a; // 1, null, 3
b; // 1, null, 3, 4, 5, 6

b.unshift(0); // instance mutation
a; // 1, null, 3
b; // 0, 1, null, 3, 4, 5, 6 !!!

每当当前实例 (b) 的突变(取消移位)使其原型(prototype)无法提供它们的值时,js 引擎似乎会自动将这些值直接复制到实例中。我不知道,但这完全有道理。

但是,使用不可变(键控/索引)对象很快就会遇到问题:

var a = [1, 2, 3];
Object.freeze(a);
var b = Object.create(a);
b.push(4, 5, 6); // Error: Cannot assign to read only property "length"
Object.freeze(b);

这个很简单:length 属性继承自不可变原型(prototype),因此不可变。解决问题并不难:

var b = Object.create(a, {length: {value: a.length, writable: true}});

但可能还会有其他问题,尤其是在更复杂的现实世界场景中。

也许有人已经处理过这个想法并且可以告诉我,是否值得对其进行推理。

阿迪特的 answer对相关问题和 Bergi 的评论触及我的问题而没有给出答案。

最佳答案

the js engine seems to copy these values straight into the instance automatically

那是因为所有数组方法(shiftpush 等)都只使用对索引的赋值(幸运的是,对 .length,这不会在非数组上自动更新)。如您所知,赋值只是在继承对象上创建一个新属性,即使原型(prototype)具有该属性(除非它具有奇怪的属性,如您的卡住长度示例)。

无论如何,您的实际问题是

Could immutable prototype chains/trees be a proper solution?

。问题是原型(prototype)链永远不会被垃圾回收。一旦所有继承的属性都被新的“变异”实例覆盖,引擎就不知道您“不再需要”原型(prototype)了——并永远保留它。
您需要手动对其进行垃圾收集(取消引用),这正是具有结构共享的 immutable.js 所做的。只有那个mutating the [[prototype]] is a bad idea ,因此您可以通过其他方式更好地管理您的结构并手动进行属性查找。

关于javascript - 使用 javascript 原型(prototype)系统创建共享结构的不可变对象(immutable对象)是否有意义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33584671/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com