JavaScript Descriptors and Named Properties


Example

Properties are members of an object. Each named property is a pair of (name, descriptor). The name is a string that allows access (using the dot notation object.propertyName or the square brackets notation object['propertyName']). The descriptor is a record of fields defining the bevahiour of the property when it is accessed (what happens to the property and what is the value returned from accessing it). By and large, a property associates a name to a behaviour (we can think of the behaviour as a black box).

There are two types of named properties:

  1. data property: the property's name is associated with a value.
  2. accessor property: the property's name is associated with one or two accessor functions.

Demonstration:

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

The property's type is determined by its descriptor's fields, and a property cannot be of both types.

Data descriptors -

  • Required fields: value or writable or both
  • Optional fields:configurable,enumerable

Sample:

{
   value: 10,
   writable: true;
}

Accessor descriptors -

  • Required fields: get or set or both
  • Optional fields: configurable, enumerable

Sample:

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

meaning of fields and their defaults

configurable,enumerable and writable:

  • These keys all default to false.
  • configurable is true if and only if the type of this property descriptor may be changed and if the property may be deleted from the corresponding object.
  • enumerable is true if and only if this property shows up during enumeration of the properties on the corresponding object.
  • writable is true if and only if the value associated with the property may be changed with an assignment operator.

get and set:

  • These keys default to undefined.
  • get is a function which serves as a getter for the property, or undefined if there is no getter. The function return will be used as the value of the property.
  • set is a function which serves as a setter for the property, or undefined if there is no setter. The function will receive as only argument the new value being assigned to the property.

value:

  • This key defaults to undefined.
  • The value associated with the property. Can be any valid JavaScript value (number, object, function, etc).

Example:

    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