Javascript Object Properties








There are two types of properties: data properties and accessor properties.

Data Properties

Data properties contain a data value. Values are read from and written to this value.

Data properties have four attributes describing their behavior:

  • Configurable - Indicates if the property can be redefined by removing the property via delete, changing the property's attributes, or changing the property into an accessor property. Default to true.
  • Enumerable - Indicates if the property will be returned in a for-in loop. Default to true.
  • Writable - Indicates if the property's value is changable. Default to true.
  • Value - Contains the actual data value for the property. Default to undefined.

When a property is explicitly added to an object, Configurable,Enumerable, and Writable are all set to true while the Value attribute is set to the assigned value.

var person = {
   name: "XML"
};

The property name is created. Value attribute is set to "XML", and any changes to that value are stored in this location.





Change attributes

To change any of the default property attributes, you must use .defineProperty() method.

This method accepts three arguments:

  • the object on which the property should be added or modified,
  • the name of the property, and
  • a descriptor object.

The properties on the descriptor object match the attribute names: configurable, enumerable, writable, and value.


var person = {};
Object.defineProperty(person, "name", {
     writable: false,/* ww  w  . j  ava  2  s  . co  m*/
     value: "XML"
});

console.log(person.name);    //"XML"
person.name = "CSS";
console.log(person.name);    //"XML"

The code above marks name property as read-only.

The code above generates the following result.





Example

The following code creates a nonconfigurable property.


var person = {};
Object.defineProperty(person, "name", {
   configurable: false,/*from  ww w. java  2  s  .co m*/
   value: "XML"
});

console.log(person.name);    //"XML"
delete person.name;
console.log(person.name);    //"XML"

The code above generates the following result.

configurable

We cannot delete a non-configurable property from the object.

Once a property has been defined as nonconfigurable, it cannot become configurable again.


var person = {};
//from  ww  w  .  java  2  s.c  o  m
Object.defineProperty(person, "name", {
    configurable: false,
    value: "XML"
});

//throws an error
//Object.defineProperty(person, "name", {
//   configurable: true,
//   value: "XML"
//});

When you are using Object.defineProperty(), the values for configurable, enumerable, and writable default to false unless otherwise specified.

Accessor Properties

Accessor properties do not contain a data value. They use a combination of a getter/setter function.

When an accessor property is read , the getter function is called. When an accessor property is written to, the setter function is called and acts on the new value.

Accessor properties have four attributes:

  • Configurable - Indicates if the property may be redefined by removing the property via delete, changing the property's attributes, or changing the property into a data property. Default to true.
  • Enumerable - Indicates if the property will be returned in a for-in loop. Default to true.
  • Get - Marks the getter function. Default to undefined.
  • Set - Marks setter function. The default value is undefined.

It is not possible to define an accessor property explicitly; you must use Object.defineProperty().


var book = {
  _year: 2004,/*www  .  ja v  a  2 s .c  om*/
  edition: 1
};

Object.defineProperty(book, "year", {
    get: function(){
       return this._year;
    },
    set: function(newValue){
       if (newValue > 2004) {
          this._year = newValue;
          this.edition += newValue - 2004;
       }
    }
});

book.year = 2005;
console.log(book.year);  
console.log(book.edition);  

book.year = 2000;
console.log(book.year);  
console.log(book.edition);  

An object is created with two properties: _year and edition. The underscore on _year is a practice to indicate that a property is not intended to be accessed from outside of the object's methods.

The code above generates the following result.

Note

It's not necessary to assign both a getter and a setter.

A property with only getter method cannot be written to. In strict mode, trying to write to a property with only a getter throws an error.

A property with only a setter cannot be read and will return the value undefined in nonstrict mode, while doing so throws an error in strict mode.

Multiple Properties

Object.defineProperties() method allows you to define multiple properties at once.


var book = {};
//from w ww . j  av  a 2 s .  c o m
Object.defineProperties(book, {
     _year: {
         value: 2004
     },

     edition: {
         value: 1
   },

   year: {
       get: function(){
           return this._year;
       },

       set: function(newValue){
           if (newValue > 2004) {
               this._year = newValue;
               this.edition += newValue - 2004;
           }
       }
   }
});
book.year = 2005;
console.log(book.year);  
console.log(book.edition);  

book.year = 2000;
console.log(book.year);  
console.log(book.edition);  

The code above generates the following result.

Reading Property Attributes

We can retrieve the property descriptor using Object.getOwnPropertyDescriptor() method.

This method accepts two arguments: the object and the name of the property.

The return value is an object with properties for configurable, enumerable, get, and set for accessor properties or configurable, enumerable, writable, and value for data properties.


var book = {};
/* www . j  a v  a 2s.com*/
Object.defineProperties(book, {
      _year: {
         value: 2004
      },
      edition: {
         value: 1
      },
      year: {
         get: function(){
            return this._year;
         },
         set: function(newValue){
            if (newValue > 2004) {
               this._year = newValue;
               this.edition += newValue - 2004;
            }
          }
       }
});

var descriptor = Object.getOwnPropertyDescriptor(book, "_year");
console.log(descriptor.value);          
console.log(descriptor.configurable);   
console.log(typeof descriptor.get);     

var descriptor = Object.getOwnPropertyDescriptor(book, "year");
console.log(descriptor.value);          
console.log(descriptor.enumerable);     
console.log(typeof descriptor.get); 

The code above generates the following result.

The Object.getOwnPropertyDescriptor() method can be used on any object in JavaScript, including DOM and BOM objects.