Export (0) Print
Expand All

Object.defineProperty Function (JavaScript)

Adds a property to an object, or modifies attributes of an existing property.

Object.defineProperty(object, propertyname, descriptor)

object

Required. The object on which to add or modify the property. This can be a native JavaScript object or a DOM object.

propertyname

Required. A string that contains the property name.

descriptor

Required. A JavaScript object that is a descriptor that describes the property. The definition can be for a data property or an accessor property.

The object that was passed to the function.

You can use the Object.defineProperty function to do the following:

  • Add a new property to an object. This occurs when the object does not have the specified property name.

  • Modify attributes of an existing property. This occurs when the object already has the specified property name.

The property definition is provided in a descriptor object, which describes the attributes of a data property or an accessor property. The descriptor object is a parameter of the Object.defineProperty function.

To add multiple properties to an object, or to modify multiple existing properties, you can use the Object.defineProperties Function (JavaScript).

A data property is a property that can store and retrieve a value. The descriptor object for a data property contains a value attribute, a writable attribute, or both.

The following table lists the attributes for a data property descriptor object.

Data descriptor attribute

Description

Default if not specified when you add a property

value

The current value of the property.

undefined

writable

true or false. If writable is set to true, the property value can be changed.

false

enumerable

true or false. If enumerable is set to true, the property can be enumerated by a for…in statement.

false

configurable

true or false. If configurable is set to true, property attributes can be changed, and the property can be deleted.

false

If the descriptor does not have a value, writable, get, or set attribute, and the specified property name does not exist, a data property is added.

When the configurable attribute is false and writable is true, the value and writable attributes can be changed.

Data Properties Added Without defineProperty

If you add a data property without using the Object.defineProperty, Object.defineProperties, or Object.create function, the writable, enumerable, and configurable attributes are all set to true. After the property is added, you can modify it by using the Object.defineProperty function.

You can use the following techniques to add a data property:

An accessor property calls a user-provided function every time that the property value is set or retrieved. The descriptor object for an accessor property contains a get attribute, a set attribute, or both.

The following table lists the attributes for an accessor property descriptor object.

Accessor descriptor attribute

Description

Default if not specified when you add a property

get

A function that returns the property value. The function has no parameters.

undefined

set

A function that has one parameter that contains the value to be assigned. The set accessor function is used to set the property value.

undefined

enumerable

true or false. If enumerable is set to true, the property can be enumerated by a for…in statement.

false

configurable

true or false. If configurable is set to true, property attributes can be changed, and the property can be deleted.

false

When a get accessor is undefined and an attempt is made to access the property value, the value undefined is returned. When a set accessor is undefined and an attempt is made to assign a value to the accessor property, nothing occurs.

If the object already has a property with the specified name, the property attributes are modified. When you modify the property, attributes that are not specified in the descriptor remain the same.

If the configurable attribute of an existing property is false, the only allowed modification is changing the writable attribute from true to false.

You can change a data property to an accessor property, and vice-versa. If you do this, configurable and enumerable attributes that are not specified in the descriptor are preserved in the property. Other attributes that are not specified in the descriptor are set to their default values.

You can incrementally define configurable accessor properties by using multiple calls to the Object.defineProperty function. For example, one Object.defineProperty call might define only a get accessor. A later call on the same property name might define a set accessor. The property would then have both a get accessor and set accessor.

To obtain a descriptor object that applies to an existing property, you can use the Object.getOwnPropertyDescriptor Function (JavaScript).

You can use the Object.seal Function (JavaScript) and the Object.freeze Function (JavaScript) to prevent the modification of property attributes.

A TypeError exception is thrown if any one of the following conditions is true:

  • The object argument is not an object.

  • The object is not extensible and the specified property name does not exist..

  • The descriptor has a value or writable attribute, and has a get or set attribute.

  • The descriptor has a get or set attribute that is not a function.

  • The specified property name already exists, the existing property has a configurable attribute of false, and the descriptor contains one or more attributes that are different from those in the existing property. However, when the existing property has a configurable attribute of false and a writable attribute of true, it is permitted for the value or writable attribute to be different.

In the following example, the Object.defineProperty function adds a data property to a user-defined object. To instead add the property to an existing DOM object, uncomment the var = window.document line.

function addDataProperty() {
    var newLine = "<br />";

    // Create a user-defined object.
    // To instead use an existing DOM object, uncomment the line below.
    var obj = {};
    //  var obj = window.document;

    // Add a data property to the object.
    Object.defineProperty(obj, "newDataProperty", {
        value: 101,
        writable: true,
        enumerable: true,
        configurable: true
    });

    // Set the property value.
    obj.newDataProperty = 102;
    document.write("Property value: " + obj.newDataProperty + newLine);

    // Output:
    //  Property value: 102
}

To list the object properties, add the following code to this example.

    var names = Object.getOwnPropertyNames(obj);
    for (var i = 0; i < names.length; i++) {
        var prop = names[i];

        document.write(prop + ': ' + obj[prop]);
        document.write(newLine);
    }

    // Output:
    //  newDataProperty: 102

To modify a property attribute for the object, add the following code to the addDataProperty function shown earlier. The descriptor parameter contains only a writable attribute. The other data property attributes remain the same.

    // Modify the writable attribute of the property.
    Object.defineProperty(obj, "newDataProperty", { writable: false });

    // List the property attributes. Use a descriptor object that
    // is obtained with the Object.getOwnPropertyDescriptor function.
    var descriptor = Object.getOwnPropertyDescriptor(obj, "newDataProperty");
    for (var prop in descriptor) {
        document.write(prop + ': ' + descriptor[prop]);
        document.write(newLine);
    }

    // Output
    //  writable: false
    //  value: 102
    //  configurable: true
    //  enumerable: true

In the following example, the Object.defineProperty function adds an accessor property to a user-defined object. To instead add the property to an existing DOM object, uncomment the var = window.document line.

function addAccessorProperty() {
    var newLine = "<br />";

    // Create a user-defined object.
    // To instead use an existing DOM object, uncomment the line below.
    var obj = {};
    // var obj = window.document;

    // Add an accessor property to the object.
    Object.defineProperty(obj, "newAccessorProperty", {
        set: function (x) {
            document.write("in property set accessor" + newLine);
            this.newaccpropvalue = x;
        },
        get: function () {
            document.write("in property get accessor" + newLine);
            return this.newaccpropvalue;
        },
        enumerable: true,
        configurable: true
    });
    // Set the property value.
    obj.newAccessorProperty = 30;
    document.write("Property value: " + obj.newAccessorProperty + newLine);

    //  Output:
    //   in property set accessor
    //   in property get accessor
    //   Property value: 30
}

To list the object properties, add the following code to this example.

    var names = Object.getOwnPropertyNames(obj);
    for (var i = 0; i < names.length; i++) {
        var prop = names[i];

        document.write(prop + ': ' + obj[prop]);
        document.write(newLine);
    }
    // Output:
    //  in property get accessor
    //  newAccessorProperty: 30

To modify a property attribute for the object, add the following code to the AddAccessorProperty function shown earlier. The descriptor parameter contains only a get accessor definition. The other property attributes remain the same.

    // Modify the get accessor.
    Object.defineProperty(obj, "newAccessorProperty", {
        get: function () { return this.newaccpropvalue; }
    });

    // List the property attributes. Use a descriptor object that
    // is obtained with the Object.getOwnPropertyDescriptor function.
    var descriptor = Object.getOwnPropertyDescriptor(obj, "newAccessorProperty");
    for (var prop in descriptor) {
        document.write(prop + ': ' + descriptor[prop]);
        document.write(newLine);
    }

    // Output:
    //  get: function () { return this.newaccpropvalue; }
    //  set: function (x) { document.write("in property set accessor" + newLine); this.newaccpropvalue = x; }
    //  configurable: true
    //  enumerable: true

The following example demonstrates how to customize built-in DOM properties. It supplements the inner functionality of the built-in innerHTML property of HTML elements. It uses the Object.getOwnPropertyDescriptor function to cache the original property descriptor before customizing the property.

function modifyDOMPrototype() {
    // Get a descriptor that contains the original innerHTML property
    // attributes. This descriptor is used by the revised set accessor
    // below.
    var originalDescriptor = Object.getOwnPropertyDescriptor(Element.prototype, "innerHTML");

    // Apply property changes to the Element prototype.
    // This revises the innerHTML set accessor for all
    // DOM element instances.
    // The get accessor continues to work as before.
    Object.defineProperty(Element.prototype, "innerHTML", {
        set: function (htmlContent) {
            // To Do: Add new set accessor code.
            // Display an alert stating that the set accessor
            // was called.
            alert("Set accessor called for " + this.id);

            // Call the original set accessor when done.
            originalDescriptor.set.call(this, htmlContent);
        }
    });

    // Get the element from the HTML body.
    var theElement = document.getElementById("TheDiv");

    alert("Original innerHTML: " + theElement.innerHTML);

    // Change the innerHTML value. This causes the revised set accessor to be called.
    theElement.innerHTML = "Revised HTML text.";

    alert("Revised innerHTML: " + theElement.innerHTML);
}

To run the example, you can add the following to the body section of the HTML:

<div id="TheDiv">This is text in an HTML division.</div>

Following is the output:

// Alert output:
//  Original innerHTML: This is text in an HTML division.
//  Set accessor called for TheDiv
//  Revised innerHTML: Revised HTML text.

// Page output:
//  Revised HTML text.

Internet Explorer 9 standards mode supports all described features.

Internet Explorer 8 standards mode supports DOM objects but not user-defined objects. The enumerable and configurable attributes can be specified, but they are not used.

Show:
© 2014 Microsoft