defineProperty、seal、freeze的使用与联系

defineProperty、seal、freeze的使用与联系

Object.defineProperty()

      Object.defineProperty(obj, "propName", {

        configurable: false, 

        enumerable: false, 

        writable: false,  

        value: "mark",

      });
数据属性 说明 默认值
configurable 属性是否可以通过delete删除并重新定义,一个属性被定义为不可配置后,就不能再变为可配置的了;不能再调用 Object.definePropert修改任何非writable的属性 true
enumerable 是否可以通过for in循环返回 true
writable 是否可以被修改 true
value 属性值 undefined

Object.seal()

只能对现有属性进行读取和需修改,不能添加新属性也不能删除已有属性

基本语法
密封一个对象会阻止其扩展并且使得现有属性不可配置。
不能添加新属性、不能删除现有属性或更改其可枚举性和可配置性、不能重新分配其原型。只要现有属性的值是可写的,它们仍然可以更改。
seal() 返回传入的同一对象

不同于 Object.freeze() 的是,通过 Object.seal() 密封的对象可以更改其现有属性,只要它们是可写的

     const person = {
        name: "jack",
        age: 24,
      };
     const re=Object.seal(person)// 返回值就是对象person本身(引用地址一样),因此person的name或age属性如果被修改,re也会变
      console.log(re,re===person); // {name: 'jack', age: 24} true
      person.age = 28;
      person.hobby='蹦迪' //非严格模式下,没有报错 没有添加进去,严格模式下回报错
      delete person.name //非严格模式下,没有报错 删除无效果,严格模式下回报错
      const obj = {};
      Object.seal(obj);
      Object.defineProperty(obj, "test", {
        value: 686,
      }); // 直接报错:object is not extensible at Function.defineProperty

严格模式下通过点的方式添加属性是会报错额

      const obj = {};
      Object.seal(obj);
      function fail() {
        "use strict";
        obj.name = "he"; // Cannot add property name, object is not extensible
      }
      fail();

非对象参数将按原样返回,不会有任何错误,因为根据定义,基本类型已经是不可变的

      function fn(params) {
        "use strict";
        const sealRe = Object.seal(true);
        console.log(sealRe);  // true
      }
      fn();

判断对象是否被密封

Object.isSealed(obj)是否是对象被密封

eg:

      const obj = {};
      Object.seal(obj);
      const bool = Object.isSealed(obj);

原理上:阻止对象的扩展,然后将现有的属性描述符更改为configurable: false。这会使对象上的属性集固定

Object.freeze()

冻结对象

基本使用

Object.freeze(obj)

      const obj = {
        name: "无名",
        age: 22,
        gender: "未知",
      };
      Object.freeze(obj);
      obj.name = "张三"; // 非严格模式下,改了不会生效,但是也不会报错;严格模式就会报错
      obj.height = 180;
      console.log(obj);
      const arr = [1, 2, 3, 4];
      Object.freeze(arr);
      // arr.push(66) // // 非严格模式下就会报错 object is not extensible at Array.push
      arr[4] = 77; // 非严格模式下,修改不生效,但是不会报错
      console.log(arr);
      const person = {
        name: "jack",
        age: 24,
        friend: {
          name: "justin",
          age: 24,
        },
      };
      Object.freeze(person);
        Object.defineProperty(person,'height',{value:188}) // 报错 object is not extensible at Function.defineProperty
        Object.defineProperty(person,'name',{value:'jackson'}) // 报错 Cannot redefine property: name at Function.defineProperty
      person.age=25 // 非严格模式下,相当于什么也没干,不会报错
        person.friend.age = 25;
       console.log(person);

严格模式会报错

      function fn() {
        "use strict";
        const obj = {
          name: "hello",
        };
        const arr = [0];
        Object.freeze(obj);
        Object.freeze(arr);
        obj.name = "你好";
        arr[1] = 1;
      }
fn()

深度冻结:

      function deepFreeze(obj) {
        const propKeys = Reflect.ownKeys(obj);
        for (let key of propKeys) {
          const value = obj[key];
          if (
            (value && typeof value === "object") ||
            typeof value === "function"
          ) {
            deepFreeze(value);
          }
        }
        return Object.freeze(obj);
      }

使用一下:

 deepFreeze(person)
 person.age=25 // 相当于什么也没干,不会报错
 person.friend.age = 25;
 console.log(person);

判断是否被冻结

     const bool= Object.isFrozen(person)
     console.log('是否被冻结',bool);

简单模拟freeze

function myFreeze(obj) {
  if (obj instanceof Object) {
    Object.seal(obj);
    for (let p in obj) {
      if (obj.hasOwnProperty(p)) {
        Object.defineProperty(obj, p, {
          writable: false
        });
        myFreeze(obj[p]);
      }
    }
  }
}

你可能感兴趣的:(js基础,javascript,前端)