JS对象之不变性

140 阅读2分钟

不变性

有时候我们需要使一个对象或者对象的属性(无论是有意还是无意的)。在ES5中可以通过多种方法来实现。

很重要的一点是,所有的方法创建的都是浅不变性,它们只会影响目标对象和它的直接属性。如果目标对象引用了其他对象(数组,函数,对象等),其他对象内容不受影响,仍然是可变的。来看一个例子:

      let person = {};

      const array = [1, 2, 3, 4];
      person.array = array;
      console.log(person.array);//[1, 2, 3, 4]
      person.array.push(5)
      console.log(person.array);//[1, 2, 3, 4, 5]
      console.log(array);//[1, 2, 3, 4, 5]

对象常量

结合configurable:falsewritable:false我们就可以创建出一个真正的常量属性

      Object.defineProperty(person, "num", {
        configurable: false,
        writable: false,
        value:2,
      });

禁止扩展

如果你想禁止一个对象添加新得属性,那么可以使用Object。preventExtensions(…)。

      const myObj = {
        a: 2,
      };
      //禁止扩展
      Object.preventExtensions(myObj);
      myObj.b = 3;
      console.log(myObj.b);//undefined

在严格模式下,会报TypeError错误!

 "use strict"
        const myObj = {
          a: 2,
        };
        //禁止扩展
        Object.preventExtensions(myObj);
        myObj.b = 3;//: Cannot add property b, object is not extensible

密封

如果我们想要一个对象,既不能添加新属性,也需要对象现有的属性不可配置(configurable:false),那么我们改怎么做呢1去使用Object.preventExtensions()然后再一个一个把对应的configurable改成false吗1不嫌麻烦是可以的,这里我们可以用到Object.seal(...),创建一个密封对象,会在现有对象上调用Object.preventExtensions,然后把所有属性的configurable改成false,密封之后不仅不能添加任何属性,也不能删除和重新配置属性(但writable还是可以从true变成false

      "use strict";
      const myObj = {
        a: 2,
        b: 3,
      };
      //将myObj密封
      Object.seal(myObj);

      //现在尝试删除属性 严格模式下报错
      console.log(delete myObj.a); //false

      //现在尝试重新配置属性
      //严格模式下报错,非严格模式,静默失败
      Object.defineProperty(myObj,"a",{// Cannot delete property "a" of #<Object>
        enumerable:true
      })

      myObj.a = 4;
      console.log(myObj.a);

      //现在尝试将writable改成false
      //严格模式下并没有报错
      Object.defineProperty(myObj, "a", {
        writable: false,
      });
      myObj.a = 5;
      console.log(myObj.a);//这里的writable:false没起作用吗?

提示,这里将writable修改成false后,虽然没有报错,但是重新写也成功了,博主暂时还不知道为什么。学到了之后再和大家分享,或者有知道的小伙伴也可以评论区留言嗷~~

冻结

Object.freeze(...)会创建一个冻结对象,这个方法实际上会调用Object.seal(...),并把所有数据访问属性标记为writable:false,这样就无法修改它们的值,

      const myObj = {
        a: 2,
        b: 3,
      };

      //冻结
      Object.freeze(myObj);
      //修改
      myObj.a = 4;
      console.log(myObj.a);//2

      //添加
      myObj.c=5
      console.log(myObj.c);//undefined

      //删除
      console.log(delete myObj.a);//false

对于Object.freeze(...),在对Vue项目进行优化的时候,如果你有一个巨大的数组或Object,并且确信数据不会修改,使用Object.freeze()可以让性能大幅提升。

new Vue({
    data: {
        // vue不会对list里的object做getter、setter绑定
        list: Object.freeze([
            { value: 1 },
            { value: 2 }
        ])
    }
}

本篇文章博主的分享就到这里啦~,有什么建议或者想说的话,可以在评论区留言嗷!