不变性(immutability),指的是一个东西被创建以后就不会发生变化了。函数式编程里的东西一般都具有这种特性。让对象具有不变性是一件好事,如果对象需要发生改变,你应该去创建一个新的对象,在新的对象里包含发生改变的部分,不要直接去修改对象本身。
下面这几个单词经常会出现:
- immutability:名词,不变性。表示东西不会发生改变的这种特性。
- immutable:形容词,不可变。可以说一个东西 immutable ,表示这个东西不会发生变化。
- mutability:名词,可变性,突变性,易变性。表示东西会发生改变的这种特性。
- mutate:动词,突变。
- mutable:形容词,可变。
在 JavaScript 里面,字符串与数字都具有不变性。也就是一个字符串一旦被创建,它的值就不会发生变化。但是 JavaScript 里的数组或对象是可变的,让它们不可变可以使用 Object.freeze 冻结一下它们(只能冻一层),也可以使用一些外部库,比如 Immutable.js。
实验一下:
let name = 'ninghao.net' undefined name[7] "." name[7] = '-' "-" name "ninghao.net"
在上面尝试修改 name 的值(把 ninghao.net 里的点“ . ” 换成 “ - ” ),办不到。因为字符串这种值不能被改变。
再试一下:
let names = ['小猫', '小狗'] undefined names[0] = '小猫咪' "小猫咪" names ["小猫咪", "小狗"] names.push('小刺猬') 3 names ["小猫咪", "小狗", "小刺猬"]
这次我们试着改变一个数组里的值,在 JavaScript 里,这是被允许的,我们改变了原数组(names)的值。数组的一些方法也会改变原数组的值,比如我们用了 push 方法,在 names 里面添加了一个新项目,这个动作修改了原数组 names 的值。
Object.freeze
Object.freeze 可以冻结对象。
实验:
let names = ['小猫', '小狗'] undefined Object.freeze(names) ["小猫", "小狗"] names[0] = '小猫咪' "小猫咪" names ["小猫", "小狗"] names.push('小刺猬') VM705:1 Uncaught TypeError: Can't add property 2, object is not extensible at <anonymous> names ["小猫", "小狗"]
这次我用 Object.freeze 冻结了一下创建的 names 数组,这样再去修改 names 数组的时候就不会影响到 names 原始的值了。
参考资料
- https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Ob...
- https://facebook.github.io/immutable-js/