• javascript-object对象属性操作之Object.defineProperty


     一、基本用法简介

        声明一个简单的对象,如下

    var obj = {
      name: 'ldld'
    }
    

     我们可以用Object.defineProperty来声明这个对象

    var obj = {}
    Object.defineProperty(obj,'name',{
      value:'ldld',
      writable:true,
      enumerable: true,
      configurable: true
    })
    

     下列就这四个基本的配置简单介绍一下

    1.   value:初始值
    2. writable:是否可以修改该属性的值
      var obj = {}
      Object.defineProperty(obj,'name',{
        value:'ldld',
        writable:false,
        enumerable: true,
        configurable: true
      })
      
      obj.name // 'ldld'
      obj.name = 'LLLL'; // 这里会修改失败,严格模式下会报错 TypeError
      console.log(obj.name) // 'ldld'
    3.    enumerable:是否可枚举,这个是否能遍历到该属性(for)
    4.   configurable : 这个得重点讲一下
      var obj = {}
      // 第一次设置操作configurable配置,设置为false
      Object.defineProperty(obj,'name',{
        value:'ldld',
        writable:true,
        enumerable: true,
        configurable: false
      })
      
      obj.name // 'ldld'
      obj.name = 'LLLL'; //  configurable: false 不影响writable属性,这里可以设置成功
      console.log(obj.name) // 'LLLL'
      
      // 第二次设置操作configurable配置,在第一步false基础上改回true
      Object.defineProperty(obj,'name',{
        value:'ldld',
        writable:true,
        enumerable: true,
        configurable: true // 现在我们想改回来,但是很遗憾,不能。不管是严格模式还是非严格模式都会报错
      })
      

       此外,configurable会影响该对象属性是否可以被删除

      Object.defineProperty(obj,'name',{
        value:'ldld',
        writable:true,
        enumerable: true,
        configurable: true
      })
      
      delete obj.name;
      console.log(obj.name) // undefined ,说明删除成功
      
      
      Object.defineProperty(obj,'name',{
        value:'ldld',
        writable:true,
        enumerable: true,
        configurable: false
      })
      
      delete obj.name;
      console.log(obj.name) // ldld, 说明name属性没有被删除


    二、对象常量

    const str = 'abc';
    str = 'def'; // 报错Uncaught TypeError: Assignment to constant variable.
    
    const obj = {name:'ldld'};
    obj.name = {
      name:'ldld1234' //  这里会修改成功
    }
    

      const声明的对象不可变,实际上是可以理解为指针的不可变。

          const str = 'abc';  表示str指针指向栈中一个地址,值'abc';

          str = 'def';表示str又指到另一个地址,值为'def',违反了不可变的规则,报错了。

          const obj = {name:'ldld'};表示obj 对象指向一个堆 内存堆的obj的引用,不管怎么改变obj里面的值,在内存堆中地方始终不变,因此不会报错。

       那么问题来了,我们想声明一个不可变的对象,那怎么办?可以参考如下:

    var obj = {}
    Object.defineProperty(obj,'name',{
      value:'ldld',
      writable:false,
      configurable: false
    })
    // 此时问obj的name属性不可改变了。
    

      但是问题来来,name是不能再改变,但是我们可以给对象扩展其他属性。。。

    三、防止对象扩展Object.preventExtensions

    var obj = {}
    Object.defineProperty(obj,'name',{
      value:'ldld',
      writable:false,
      configurable: false
    })
    // 此时问obj的name属性不可改变了。但是可以扩展obj属性
    obj.age = 100;
    console.log(obj.age) // 100 
    
    Object.preventExtensions(obj);
    obj.sex = 'male';
    console.log(obj.sex) // undefined,说明扩展失败
    

      

    四、密封Object.seal

    顾名思义,密封一个对象,这个对象不能配置,不能扩展属性,不能删除属性。但是可以可以修改熟悉过的值

    Object.seal(obj)// 等同于如下:代码1 + 代码2
    // 代码1
    Object.defineProperty(obj,'[该对象所有的属性]',{
      configurable: false
      // writable:true, // 此时默认为true,可以修改
    })
    // 代码2
    Object.preventExtensions(obj);
    

      

    四、冻结Object.freeze(obj)

    Object.freeze(obj)// 等同于如下:代码1 + 代码2
    // 代码1
    Object.seal(obj)
    // 代码2 
    Object.defineProperty(obj,'[该对象所有的属性]',{
      writable:false
    })
    

      

    由此可见,冻结,就是定一个对象常量的终极大法。

        




  • 相关阅读:
    vue + element-ui实现动态多级表头
    Linux 系统编程 学习:11-线程:线程同步
    Linux 系统编程 学习:10-线程:线程的属性
    Linux 系统编程 学习:9-线程:线程的创建、回收与取消
    Linux 网络编程的5种IO模型:信号驱动IO模型
    Linux 系统编程 学习:8-基于socket的网络编程3:基于 TCP 的通信
    Linux 系统编程 学习:6-基于socket的网络编程1:有关概念
    Linux 系统编程 学习:7-基于socket的网络编程2:基于 UDP 的通信
    Linux 系统编程 学习:5-进程间通信2:System V IPC
    Linux 系统编程 学习:2-进程间通信1:Unix IPC(1)管道
  • 原文地址:https://www.cnblogs.com/ldld/p/10853951.html
Copyright © 2020-2023  润新知