Objeto mutable
En JavaScript, los objetos son datos de tipo de referencia. La ventaja es que cuando los objetos se modifican con frecuencia, se modifican en función del objeto original y no necesitan ser recreados. Esto puede utilizar efectivamente la memoria y no causará un desperdicio de espacio de memoria. Esta característica de los objetos puede llamarse mutable, lo que significa "mutable" en chino.
Para objetos mutables, su flexibilidad y cambio a veces pueden convertirse en sus desventajas. Cuanto más flexibles y cambiantes sean los datos, más difícil será controlar. Para un objeto con una estructura compleja, los datos se modifican accidentalmente inadvertidamente. Si el objeto se usa en múltiples ámbitos, es difícil prever si los datos cambiarán y cuándo.
var obj = { /* 一个复杂结构的对象*/ };doSomething(obj);// 上面的函数之行完后,此时的obj 还是最初的那个obj 吗?Para abordar este problema, una solución convencional puede copiar un nuevo objeto copiando profundamente el objeto y luego modificándolo en el nuevo objeto. Esto puede garantizar la capacidad de control de los datos, pero la copia frecuente causará una gran pérdida de espacio de memoria.
var obj = { /* 一个复杂结构的对象*/ };// copy 出一个新的obj2// 但是copy 操作会浪费内存空间var obj2 = deepClone(obj);doSomething(obj2);// 上面的函数之行完后,无论obj2 是否变化,obj 肯定还是原来那个objObjeto inmutable
Para resolver mejor los problemas anteriores, aparece el objeto inmutable, que es "inmutable" literalmente traducido al chino. Cada vez que se modifica un objeto inmutable, se crea un nuevo objeto inmutable. La operación en el nuevo objeto no afectará los datos del objeto original. This special object is not the new functional feature of JavaScript, but a set of solutions provided by the industry to solve this problem, and some excellent open source libraries have emerged, the most famous of which is Facebook's Lee Byron's open source immutable.js. Por supuesto, la solución de Immutable no es original, pero proviene de Clojure y Scala.
Comparación de rendimiento entre mutable e inmutable
对于Mutable 的对象的低效率操作主要体现在复制和比较上,而Immutable 对象就是解决了这两大低效的痛点。
La operación de copia profunda de los objetos mutables ordinarios copiará todos los datos. The Immutable object will not copy the entire data when modifying the data, but will transfer the parent-child relationship between the changed node and the unchanged node to a new node, similar to the structure of a linked list. Desde la perspectiva de la "copia", se logra la minimización de la replicación y se comparten las piezas no cambiadas. Mutable es "lleno" al copiar, mientras que inmutable es "incremental", lo que determina la alta o baja tasa de uso del espacio de memoria.
Y según la característica de que cada vez que se modifica un objeto inmutable, se creará un nuevo objeto inmutable. Esto puede guardar el estado modificado de los datos en un conjunto de instantáneas, que también es bastante conveniente.
Hablemos de la operación de comparación. Para objetos mutables, si desea comparar si los dos objetos son iguales, debe atravesar cada nodo del objeto para comparar. Para los objetos con estructuras complejas, su eficiencia definitivamente no es mucho más alta. Para objetos inmutables, Immutable.js proporciona una API que determina directamente si los "valores" de dos objetos inmutables son iguales.
var map1 = Immutable.map ({A: 1, B: 1, C: 1}); var map2 = Immutable.map ({a: 1, b: 1, c: 1}); afirmar (map1! == map2); // Para diferentes instancias inmutables, la dirección de referencia afirma (Immutable.is (MAP1, MAP2)); // Los valores de MAP1 y MAP2 son iguales, y los valores afirman (MAP1.Equals (MAP2)); // Las funciones de Immutable.Is son las mismasEn las aplicaciones de desarrollo reales, el rendimiento no siempre es el más crítico e importante. For ordinary JavaScript projects, the controllability of data brought about by the characteristics of Immutable is more advantageous than performance. For Mutable objects, it is suitable for use in a closed scope, while Immutable objects are suitable for use when data needs to be passed across multiple scopes.
La diferencia entre mutable e inmutable
immutable.js 提供了多种Immutable 的数据结构:包含了List Stack Map OrderedMap Set OrderedSet Record,这些数据结构与原生的Mutable 的数据结构大致对应。
各数据结构的用法这里不细说,主要说说Immutable 对象与Mutable 对象在使用上的区别吧。
Los objetos mutables nativos son muy convenientes para "leer" y "escribir".
var mutableObj = {}; // Escribir datos mutablesBj.foo = 'bar'; // leer data console.log (mutableBj.foo);El objeto inmutable debe "leer" y "escribir" los datos a través de SET y GET.
var immutableObj1 = Immutable.Map();// Write data var immutableObj2 = immutableObj1.set('foo', 'bar');// Read data console.log(immutableObj2.get('foo')); // => 'Bar'上面的例子为了说明set 方法的使用才在一开始创建了一个空对象,实际上可以在实例化的时候传初始值。
var inmutableBj = Immutable.map ({'foo', 'bar'});Para datos con niveles más profundos, la interfaz de acceso proporcionada por Immutable.js es muy conveniente.
Var ImmutableBj1 = Immutable.FromJS ({A: {B: 'C'}, D: [1, 2, 3]}); // Leer Data Deep Console.log (ImmutableBj1.getin (['A', 'B'])); // => 'c'console.log (ImmutableBj1.getin ([' a ',' b '])); // => 2 // Modifique los datos profundos var ImmutableBj2 = ImmutableBj1.setin (['a', 'b'], 'd'); console.log (inmutableBj2.getin (['a', 'b'])); // => 'D'如果是原生的Mutable 对象,在链式访问一个深层级的数据时可能会报对象undefined 的错误,而Immutable 对象在碰到这种情况时不会报错,返回的是undefined。
在调试的时候,如果想查看一个Immutable 对象的内部结构,建议使用toJSON() 先转换为普通的Mutable 对象。