zoukankan      html  css  js  c++  java
  • 理解属性描述对象

    1.概述

    JavaScript提供了一个内部数据结构,用来描述一个对象的属性的行为,控制它的行为。这被称为“属性描述对象”(attributes object)。每个属性都有自己对应的属性描述对象,保存该属性的一些元信息。

    实例:

    {
      value: 123,
      writable: false,
      enumerable: true,
      configurable: false,
      get: undefined,
      set: undefined
    }
    
    属性描述对象提供6个元属性。
    
    (1)value
    
    value存放该属性的属性值,默认为undefined。
    
    (2)writable
    
    writable存放一个布尔值,表示属性值(value)是否可改变,默认为true。
    
    (3)enumerable
    
    enumerable存放一个布尔值,表示该属性是否可枚举,默认为true。如果设为false,会使得某些操作(比如for...in循环、Object.keys())跳过该属性。
    
    (4)configurable
    
    configurable存放一个布尔值,表示“可配置性”,默认为true。如果设为false,将阻止某些操作改写该属性,比如,无法删除该属性,也不得改变该属性的属性描述对象(value属性除外)。也就是说,configurable属性控制了属性描述对象的可写性。
    
    (5)get
    
    get存放一个函数,表示该属性的取值函数(getter),默认为undefined。
    
    (6)set
    
    set存放一个函数,表示该属性的存值函数(setter),默认为undefined。
    

    ECMAScript中属性特性又分为两种属性:数据属性和访问器属性。

    (1)数据属性

    用来描述一个对象的属性的行为,控制它的行为

    1.可枚举性(enumerable): 
    可枚举性(enumerable)用来控制所描述的属性,是否将被包括在for...in循环之中。 默认true
    
    2.可配置性(configurable): 
    可配置性(configurable)决定了是否可以修改属性描述对象。 默认true
    
    3.可写性(writable):
    可写性(writable)决定了属性的值(value)是否可以被改变。 默认true,Value 包含这个属性的数据值  默认值为undefined
    

    (2)访问器属性(该属性的值不是实际存在的,而是每次读取时计算生成的)

    除了直接定义以外,属性还可以用存取器(accessor)定义。其中,存值函数称为setter,使用set命令;取值函数称为getter,使用get命令。

    var o = {
      get p() {
        return 'getter';
      },
      set p(value) {
        console.log('setter: ' + value);
      }
    };
    
    
    o.p // "getter"
    o.p = 123 // "setter: 123"
    

    2.使用Object()自身静态方法对其操作

    (1)使用Object.getOwnPropertyDescriptor()读出对象自身属性的属性描述对象

    var o = { p: 'a' };
    
    Object.getOwnPropertyDescriptor(o, 'p')
    // Object { value: "a",
    //   writable: true,
    //   enumerable: true,
    //   configurable: true
    // }
    

    (2)使用Object.defineProperty(),Object.defineProperties()定义或改写属性,然后返回修改的对象

    语法:Object.defineProperty(object, propertyName, attributesObject)
    第一个是属性所在的对象,第二个是属性名(它应该是一个字符串),第三个是属性的描述对象。
    
    var o = Object.defineProperty({}, 'p', {//定义一个属性
      value: 123,
      writable: false,
      enumerable: true,
      configurable: false
    });
    
    var o = Object.defineProperties({}, {//定义多个属性
      p1: { value: 123, enumerable: true },
      p2: { value: 'abc', enumerable: true },
      p3: { get: function () { return this.p1 + this.p2 },
        enumerable:true,
        configurable:true
      }
    });
    
    o.p1 // 123
    o.p2 // "abc"
    o.p3 // "123abc"
    

    (3)使用Object.getOwnPropertyNames()方法返回直接定义在某个对象上面的全部属性的名称,不管该属性是否可枚举。

    var o = Object.defineProperties({}, {
      p1: { value: 1, enumerable: true },
      p2: { value: 2, enumerable: false }
    });
    
    Object.getOwnPropertyNames(o)
    // ["p1", "p2"]
    

    (4)使用Object.prototype.propertyIsEnumerable()方法用来判断一个属性是否可枚举。

    var o = {};
    o.p = 123;
    
    o.propertyIsEnumerable('p') // true
    o.propertyIsEnumerable('toString') // false
    
    用户自定义的p属性是可枚举的,而继承自原型对象的toString属性是不可枚举的。
    

    下面是控制对象状态的一些方法

    Object.preventExtensions():防止对象扩展。
    Object.isExtensible():判断对象是否可扩展。
    Object.seal():禁止对象配置。
    Object.isSealed():判断一个对象是否可配置。
    Object.freeze():冻结一个对象。
    Object.isFrozen():判断一个对象是否被冻结。
    

    链接:有关属性描述对象的更加详细内容看阮老师的属性描述对象一文。

  • 相关阅读:
    android cocos2d-x视频
    Android OpenGL 学习笔记 --开始篇
    Nginx配置详解
    扩展RBAC用户角色权限设计方案
    几种序列化与Get、Set方法的关系
    Kettle大量数据快速导出的解决方案(利用SQL导出百万级数据,挺快的)
    SpringBoot 标准集成MyBatis的2种方式
    Apache Commons io FileUtils 详解
    SpringBoot在工具类中读取配置文件(ClassPathResource)
    利用guava封装RateLimiter 令牌桶算法(AOP实现)
  • 原文地址:https://www.cnblogs.com/yf2196717/p/12843601.html
Copyright © 2011-2022 走看看