JavaScript Objects in Depth
You have already learned about JavaScript object in the JavaScript Basics section. Here, you will learn about object in detail.
As you know, object in JavaScript can be created using object literal, object constructor or constructor function. Object includes properties. Each property can either be assigned a literal value or a function.
Consider the following example of objects created using object literal and constructor function.
// object literal
var person = {
firstName:'Steve',
lastName:'Jobs'
};
// Constructor function
function Student(){
this.name = "John";
this.gender = "Male";
this.sayHi = function(){
alert('Hi');
}
}
var student1 = new Student();
console.log(student1.name);
console.log(student1.gender);
student1.sayHi();
In the above example, person
object is created using object literal that includes firstName
and lastName
properties and student1
object is created using constructor function Student
that includes name, gender and sayHi properties where function is assigned to sayHi
property.
Use Object.keys() method to retrieve all the properties name for the specified object as a string array.
function Student(){
this.title = "Mr.";
this.name = "Steve";
this.gender = "Male";
this.sayHi = function(){
alert('Hi');
}
}
var student1 = new Student();
Object.keys(student1);
["title", "name", "gender", "sayHi"]
Use for-in loop to retrieve all the properties of an object as shown below.
function Student(){
this.title = "Mr.";
this.name = "Steve";
this.gender = "Male";
this.sayHi = function(){
alert('Hi');
}
}
var student1 = new Student();
//enumerate properties of student1
for(var prop in student1){
console.log(prop);
}
title name gender sayHi
Property Descriptor
In JavaScript, each property of an object has property descriptor which describes the nature of a property. Property descriptor for a particular object's property can be retrieved using Object.getOwnPropertyDescriptor()
method.
Object.getOwnPropertyDescriptor(object, 'property name')
The getOwnPropertyDescriptor method returns a property descriptor for a property that directly defined in the specified object but not inherited from object's prototytpe.
The following example display property descriptor to the console.
var person = {
firstName:'Steve',
lastName:'Jobs'
};
function Student(){
this.name = "John";
this.gender = "Male";
this.sayHi = function(){
alert('Hi');
}
}
var student1 = new Student();
console.log(Object.getOwnPropertyDescriptor(person,'firstName'));
console.log(Object.getOwnPropertyDescriptor(student1,'name'));
console.log(Object.getOwnPropertyDescriptor(student1,'sayHi'));
Object {value: "Steve", writable: true, enumerable: true, configurable: true}
Object {value: "John", writable: true, enumerable: true, configurable: true}
Object {value: function, writable: true, enumerable: true, configurable: true}
As you can see in the above output, the property descriptor includes the following 4 important attributes.
Attribute | Description |
---|---|
value | Contains an actual value of a property. |
writable | Indicates that whether a property is writable or read-only. If true than value can be changed and if false then value cannot be changed and will throw an exception in strict mode |
enumerable | Indicates whether a property would show up during the enumeration using for-in loop or Object.keys() method. |
configurable | Indicates whether a property descriptor for the specified property can be changed or not. If true then any of this 4 attribute of a property can be changed using Object.defineProperty() method. |
Object.defineProperty()
The Object.defineProperty() method defines a new property on the specified object or modifies an existing property or property descriptor.
Object.defineProperty(object, 'property name', descriptor)
The following example demonstrates modifying property descriptor.
'use strict'
function Student(){
this.name = "Steve";
this.gender = "Male";
}
var student1 = new Student();
Object.defineProperty(student1,'name', { writable:false} );
try
{
student1.name = "James";
console.log(student1.name);
}
catch(ex)
{
console.log(ex.message);
}
The above example, it modifies writable attribute of name
property of student1
object using Object.defineProperty()
. So, name
property can not be changed. If you try to change the value of name
property then it would throw an exception in strict mode. In non-strict mode, it won't throw an exception but it also won't change a value of name property either.
The same way, you can change enumerable property descriptor as shown below.
function Student(){
this.name = "Steve";
this.gender = "Male";
}
var student1 = new Student();
//enumerate properties of student1
for(var prop in student1){
console.log(prop);
}
//edit enumerable attributes of name property to false
Object.defineProperty(student1,'name',{ enumerable:false });
console.log('After setting enumerable to false:');
for(var prop in student1){
console.log(prop);
}
name
gender
After setting enumerable to false:
gender
In the above example, it display all the properties using for-in loop. But, once you change the enumerable attribute to false then it won't display name
property using for-in loop. As you can see in the output, after setting enumerable attributes of name property to false, it will not be enumerated using for-in loop or even Object.keys() method.
The Object.defineProperty() method can also be used to modify configurable attribute of a property which restrict changing any property descriptor attributes further.
The following example demonstrates changing configurable attribute.
'use strict';
function Student(){
this.name = "Steve";
this.gender = "Male";
}
var student1 = new Student();
Object.defineProperty(student1,'name',{configurable:false});// set configurable to false
try
{
Object.defineProperty(student1,'name',{writable:false}); // change writable attribute
}
catch(ex)
{
console.log(ex.message);
}
In the above example, Object.defineProperty(student1,'name',{configurable:false});
sets configurable attribute to false which make student1 object non configurable after that. Object.defineProperty(student1,'name',{writable:false});
sets writable to false which will throw an exception in strict mode because we already set configurable to false.
Define New Property
The Object.defineProperty() method can also be used to define a new properties with getters and setters on an object as shown below.
function Student(){
this.title = "Mr.";
this.name = "Steve";
}
var student1 = new Student();
Object.defineProperty(student1,'fullName',{
get:function(){
return this.title + ' ' + this.name;
},
set:function(_fullName){
this.title = _fullName.split(' ')[0];
this.name = _fullName.split(' ')[1];
}
});
student1.fullName = "Mr. John";
console.log(student1.title);
console.log(student1.name);
Mr.
John