描述符和命名属性

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

有两种类型的命名属性:

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

示范:

obj.propertyName1 = 5; //translates behind the scenes into
                       //either assigning 5 to the value field* if it is a data property
                //or calling the set function with the parameter 5 if accessor property

//*actually whether an assignment would take place in the case of a data property
//also depends on the presence and value of the writable field - on that later on

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

数据描述符 -

  • 必填字段:valuewritable 或两者
  • 可选字段:configurableenumerable

样品:

{
   value: 10,
   writable: true;
}

访问者描述符 -

  • 必填字段:getset 或两者
  • 可选字段:configurableenumerable

样品:

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

字段的含义及其默认值

configurableenumerablewritable

  • 这些键都默认为 false
  • 当且仅当可以更改此属性描述符的类型并且可以从相应对象中删除属性时,configurable 才是 true
  • 当且仅当在枚举相应对象上的属性期间显示此属性时,enumerable 才是 true
  • 当且仅当与属性关联的值可以使用赋值运算符更改时,writable 才是 true

getset

  • 这些键默认为 undefined
  • get 是一个作为属性 getter 的功能,如果没有 getter 则可以作为 getter。函数 return 将用作属性的值。
  • set 是一个函数,可以作为属性的设置者,如果没有 setter,则为 undefined。该函数将仅接收分配给属性的新值作为参数。

value

  • 此键默认为 undefined
  • 与属性相关的价值。可以是任何有效的 JavaScript 值(数字,对象,函数等)。

例:

    var obj = {propertyName1: 1}; //the pair is actually ('propertyName1', {value:1,
                                                                    // writable:true,
                                                                    // enumerable: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')
                      //will be treated like it has enumerable:false, configurable:false
                                                }});
//propertyName1 is the name of obj's data property 
//and propertyName2 is the name of its accessor property

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

obj.propertyName2 = 3; //and this will be logged every time propertyName2's value is tried to be set
console.log(obj.propertyName2); //this will be logged every time propertyName2 is accessed to get its value