JavaScript中的可变数据和不可变数据有什么区别?

时间:2019-05-17 15:38:44

标签: javascript data-structures

我想知道JavaScript中可变数据和不可变数据之间的区别是什么。我们使用哪一个真的重要吗?在任何情况下都首选使用一种而不是另一种吗?

谢谢。

2 个答案:

答案 0 :(得分:0)

  

[W] JavaScript [?]中的可变数据和不可变数据有何区别?

可变值可以被突变。在JS中,原语(数字,字符串,布尔值)是不可变的,这意味着您无法对其进行更改,要对其进行变异,必须创建一个应用了条件的新原语,而对象是可变的(除非冻结),因此您可以添加/更改/删除对象本身的属性。使用letvar声明变量时可以将其更改,而使用const声明时则不可变。

  5 + 5 // this does not change the "5" itself, it creates a new number value, containing "10"
 let str = "test";
 str += "test2"; // Although it looks as if this would mutate the string, it actually creates a new one and stores that under "str" again

 const infinite = 42; // a primitive inside of a constant can't be mutated, and the variable can't be changed, so "infinite" will always be 42

 const reference = { mutable: 1 }; // Although the variable itself can't be changed, the object it is referencing can be
 reference.mutable = 2;

 Object.freeze(reference); // by freezing an object you can make it immutable
reference.mutable = "won't work";

因此,尽管存在一些技术上可变且不可变的值,但也有一些约定不可变的值(因此文档将告诉您更改它们)。一个例子就是React中的状态。虽然您可以直接更改状态对象,但不应该这样做(因为状态更改应反映到显示的页面上,这就是使用setState来重新设置状态的原因,它也会重新呈现)。

  

我们使用哪一个真的重要吗?在任何情况下都首选使用一种而不是另一种吗?

不可更改的数据结构的更改成本通常更高,因为在应用更改之前必须先复制基础数据。但是,您可以安全地共享不可变的对象,因为您知道它们将来不会被突变,如果对象被大量共享,这可能是有益的。

  let immutable = { value: 1 }; // let's say this object is immutable by convention
 share(immutable); // then we know for sure that even if "dhare" stores a reference to the object and accesses it later, the value won't be changed
 immutable = { ...immutable, value: 2 }; // this won't affect the other object, as we cloned it and changed the clone

也就是说,各种形式的可变状态总是在增加代码的复杂性。如果代码的某些部分崩溃,则必须找出函数访问时可变数据结构所处的状态。在异步系统中,这是一项艰巨的任务。如果使用不可变数据结构并保持函数纯净,则可以轻松地将错误与导致错误的输入相关联,这使事情变得更加容易。

  let bad = 1, global = 2, state = 3;

  // This will log NaN somewhen ... but why ... ?! It isn't clear if we only see this code
  setInterval(() => console.log(bad / global / state));

 // ... because somewhere else at a different place, state gets re set:

 setInterval(() => state = Math.random() * 10);

通常,您应始终使事物保持不变/局部,仅在需要时使用可变/共享状态(出于性能/逻辑原因)。

答案 1 :(得分:0)