How else you can define properties for JavaScript objects
Tags: javascript, oop
Published: 2018-11-24 10:27:31

---
title: How else you can define properties for JavaScript objects
published: true
description: A short introduction in Object.defineProperty method, for objects' properties control and customisation
tags: javascript, oop, js
---

JavaScript is an awesome technology. It's really flexible, and allows cool runtime object manipulation, which are not such a headache like in case with Ruby (though that's my personal opinion after working with both).

## The common way of properties definition

Well, there are several ways of default properties definition. First one is using object initializer literal. For instance let's have the `Car` object:

```javascript
var Car = {
    brand: 'Toyota',
    model: 'Prius',
    engine: {
        state: 'off'
    },
    turnOn: function() {
        this.engine.state = 'on'
        console.log('Engine is:', this.engine.state)
    }
}
```

This way object's properties are accessible from the outside world, like:

```javascript
Car.brand // => "Toyota"
Car.brand = 'Honda'
Car.brand // => "Honda"

Car.engine.state // => "off"
Car.turnOn() // => "Engine is: on"
Car.engine.state // => "on"
```

And can be changed with values of other type.

Another way of property definition is in the function constructor using `this` keyword, which will reference to current `Function` object:

```javascript
function Car() {
    this.brand = 'Toyota'
    this.model = 'RAV 4'
    this.engine = {
        state: 'off'
    }
}
```

and they are also accessible from the outside world:

```javascript
var car = new Car()

car.brand // => "Toyota"
car.brand = 'Honda'
car.brand // => "Honda"
```

But there are some additional features for property definitions in JavaScript which will be described in next section.

## Defining property using <b>Object.defineProperty</b> method

According to [documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty#Syntax), this is a `Object`'s static method, which takes an object as first parameter, the name of new property as the second parameter, and an object with options. Let's see the next example:

```javascript
var Car = {
    brand: 'Toyota'
}

Object.defineProperty(Car, 'brand', {
  writable: false,
})

Car.brand // => "Toyota"
Car.brand = 'BMW'
Car.brand // => "Toyota"
```

This way, the `brand` property can not be overwritten from the outside world. This way, it is possible to set all the aspects of an object property, and gives a good portion of control over the objects' properties. Here are some other options, that should be taken in account:

- <b><u>configurable</u></b> - has `false` as default, and will allow to change the type of this property or delete the property from this current object if the value will be `true`

- <b><u>enumerable</u></b> - this will indicate if this property should be shown during enumeration, and it will do so only if it's value will be `true`. By default it is `false`

- <b><u>writable</u></b> - `true` if this property should be changed with an assignment operator `=`. Default to `false`

- <b><u>value</u></b> - it would take any value of any valid, specific type, like number, object, function, etc.

- <b><u>get</u></b> - this property can take a function as a value and it will override the property value extraction of object through which the property is accessed

- <b><u>set</u></b> - this property can take a function as a value with a single argument, which can override the logic of assignment operator of object through which the property is accessed.

Let's consider a more complex example. If there is a need to manipulate some other data inside an object, without specific method invocation, it is wise to customise the `set` property of object property, as follows:

```javascript
function CustomGettersSetters() {
    var a = null;
    var history = [];

    Object.defineProperty(this, 'a', {
        get() {
            console.log('Inside getter')
            return a
        },
        set(arg) {
            console.log('Inside setter')
            history.push(arg)
            a = arg
            return true
        }
    })

    this.getHistory = function() { return history }
}

var custom = new CustomGettersSetters();

custom.a // will log "Inside getter" and return `null`
custom.a = '321' // will log "Inside setter", push a value to `history`, and will set value to `a`
custom.a = 764 // will log "Inside setter", push a value to `history`, and will set value to `a`
custom.a // will log "Inside getter" and return `764`
custom.history // will return `undefined`
custom.getHistory() // will return an array ["321", 764]

```

This way there was added an additional functionality for the current object, without any need for any additional method calls.

## Conclusion

The `Object.defineProperty` method is a very powerfull tool for object property manipulation, as it allows some sort of control over it, which can be useful at some point. There is also `Object.defineProperties` which can create multiple properties in similar way. The difference is that it takes two parameters: first is the object which will have new properties, and second would be an object of properties, which also will contain an object of options mentioned above.