JavaScript 描述符和命名属性

示例

属性是对象的成员。每个命名属性都是一对(名称,描述符)。该名称是允许访问的字符串(使用点符号object.propertyName或方括号符号object['propertyName'])。描述符是对字段的记录,这些字段定义了访问属性时的行为(属性发生了什么以及访问该属性返回的值是什么)。总的来说,属性将名称与行为相关联(我们可以将行为视为黑盒)。

命名属性有两种类型:

  1. 数据属性:属性的名称与一个值相关联。

  2. accessor属性:该属性的名称与一个或两个访问器函数关联。

示范:

obj.propertyName1 = 5; //在幕后翻译成
                       //如果它是数据属性,则将5赋给value字段*
                //或使用accessor属性使用参数5调用set函数


//*实际上是在数据属性的情况下是否会发生分配
//还取决于可写字段的存在和值-稍后

属性的类型由其描述符的字段确定,并且属性不能同时属于这两种类型。

数据描述符-

  • 必填字段:value或writable或两者

  • 可选字段:configurable,enumerable

样品:

{
   value: 10,
   writable: true;
}

访问器描述符-

  • 必填字段:get或set或两者

  • 可选字段:configurable,enumerable

样品:

{
    get: function () {
        return 10;
    },
    enumerable: true
}

字段的含义及其默认值

configurable,enumerable以及writable:

  • 这些键均默认为false。

  • configurable是true当且仅当该属性描述符的类型可以改变,并且如果该属性可以由相应的对象被删除。

  • enumerable是true当且仅当该属性对应的对象的属性的枚举期间显示出来。

  • writable是true当且仅当与所述属性相关联的值可以与一个赋值操作符改变。

get和set:

  • 这些键默认为undefined。

  • get是用作属性的吸气剂的函数,或者undefined如果没有吸气剂的函数。函数返回值将用作属性的值。

  • set是用作属性的setter的函数,或者undefined如果没有setter的函数。该函数将仅将分配给属性的新值作为参数。

value:

  • 此项默认为undefined。

  • 与属性关联的值。可以是任何有效的JavaScript值(数字,对象,函数等)。

例:

    var obj = {propertyName1: 1}; //该对实际上是('propertyName1',{value:1,
                                                                    // 可写:true,
                                                                    // 枚举:true,
                                                                    // configurable:true})
    Object.defineProperty(obj, 'propertyName2', {get: function() {
                                                    console.log('this will be logged ' + 
                                 'every time propertyName2 is accessed to get its value');
                                                },
                                            set: function() {
                                                    console.log('and this will be logged ' + 
                                'every time propertyName2\'s value is tried to be set')
                      //将被视为具有枚举:假,可配置:假
                                                }});
//propertyName1是obj的数据属性的名称 
//propertyName2是其访问者属性的名称





obj.propertyName1 = 3;
console.log(obj.propertyName1); //3

obj.propertyName2 = 3; //并且每次尝试设置propertyName2的值时都会记录
console.log(obj.propertyName2); //每次访问propertyName2以获取其值时,将记录此事件