JavaScript Objects

Exploring JavaScript objects and their properties.
On this page

1.0 Object Oriented Programming

JavaScript was not at all intended to be an Object Oriented Programming Language. At the time of its creation there were already other languages present which were doing this task, namely C++ was the modified version of C with Classes and other object oriented features. Another language which took the grounds was Java which was basically designed to serve the concept revolving around Object Oriented Programming and to overcome the shortcomings present in C++.

JavaScript was not introduced for such a programming concept yet the designer was aware of the paradigm shift, which was moving from procedural programming to Object oriented programming. Therefore to say that it was an Object Oriented Programming Language would be completely unfair. No Programmer who knew C++ and Java or any other language like small-talk would agree that JavaScript was not meant to be Object Oriented. However, it had the facilities provided by the designer to have some features of Object Oriented Languages. For example to share the code from other object JavaScript use prototypal inheritance as opposed to class inheritance. Similarly JavaScript also provided features of functional programming such as treating functions as values and passed around to other functions which is only found in functional language. Thus to summarise, JavaScript is a prototypal based functional language which has evolved in last two decades.

1.1 Objects Data Type

An individual piece of data is usually stored in a variable of some type but when you have number of variables which relates to a single entity then they are usually stored in some sort of structure so they can be more easily defined, maintained and manipulated while having interaction with other units. JavaScript way of grouping related variables in a self contained unit is to store each of them in key/name and its value pair, known as properties of the object and their values. This technique of storing variables is known as associative arrays, dictionary or hash tables. Since the key is stored as a string , It basically provides a mapping between key {string} to value thus also known as map.

One of the uses of objects is to organize self contained unit possessing some properties and providing some methods. Before ECMAScript-6 there was no concept of classes in JavaScript and inheritance was implemented through a special property __proto__ called Prototype. But with ECMAScript-6 class syntax is introduced to help programmers coming from class based object oriented language. This introduction is only regarded as synthetic sugar coated technique, what does it mean is that internal system is same as before.

2.0 Creating JavaScript Objects

  • In JavaScript there are different ways to create an object which way you choose depends upon its use. Some of common ways of creating the object are mentioned below followed by their examples.
  1. Using literals var obj = { } // ECMAScript-3
  2. Using Object constructor var obj = new Object() // ECMAScrip-3
  3. Using Constructor function var obj = new <function name>
  4. Using Object.create(prototype) from a given prototype // ECMAScript-5
  5. Using classes and instantiating the object class <identifier>{ .....} // ECMAScript-6

2.1 Creating Objects with Literal { }

  • The easiest and preferred way of creating an object is to create it with curly brackets known as Literal notation.
1var obj = {} //an empty object
  • A name does not have to be generic, it can be descriptive so that it makes us easy to comprehend.
1var obj = {}
  • In above case, JS provides a quick way of creating an object which is created internally using the special function called constructor function. it does not have any state as no members exist yet. But properties and methods can be added later on when needed. This way of adding properties is regraded as expando properties and regarded as extending the object.

2.2 Properties of Objects

  • Until ECMAScript-5 there has been two ways to define properties of objects but ECMAScript-5 introduced a new way to define the property with more control over them;

  • At the time of object creation,var myObject = {x: 10 , y: 20}.

  • Assign properties to object by extending the object, known as expando property,mObject.z = 30

  • Use ECMAScript-5 provided built in methods Object.defineProperty({obj,prop,itsValue}) for a single property or for more than one use Object.defineProperties(obj......).

  • The first way is to define the properties at the time of object creation. So when an object is created they already have he properties of the object The second way is to add properties to the object after the object has been created. This is a very useful which allows you to add more properties on the fly to any object and delete them when not needed. These properties are also known as expando properties and done by extending the object.

  • Prior to ECMAScript-5, properties had only one attribute, that is every property had its value but ECMAScript-5 added other attributes using the property descriptor object.

2.3 What is JS property descriptor

  • A property descriptor is another object that holds information about the properties, it is sort of meta data object. It can be of two types either Data Descriptor or Accessor Descriptor. In JS it is also a separate object created whenever an object gets created to keep track of new object’s properties. It can be accessed using Object.getOwnPropertyDescriptor(obj) function. Data Descriptor deals with the four properties of the descriptor object {value: "",writable:"",enumerable:"",configurable:""} while Accessor Descriptor deals with get or set or with both of them.

2.4 Properties’ attributes

  • Property attributes can be set at the time of creating properties but if not created explicitly, they get default values assigned to them. Let’s see what are those default values;
1var x
2Object.getOwnPropertyDescriptor(global, 'x')
3/*{ value: undefined,  writable: true,  enumerable: true,  configurable: false }*/
  • Value Its value assigned when you declared a variable, if not it gets the default value of undefined.

  • Writable means that the old value can be deleted and new values can be assigned by default it is assigned true thus can be updated.

  • Enumerable:As the name indicates that if set to true the variable can be accessed using enumeration like for..in loop or using object.keys. And can be saved permanently using JSON.stringify method. By default it is assigned true. In case of being false this property is not enumerated.

  • Configurable:To control the above two attributes behaviour i.e., whether the above two can be set to other values or not. If allowed that is configurable = true , they can be set to either true or false . But if configurable = false the above two can not be changed. Their attributes remains as it is as the time of creation and the property can not be deleted.

2.5 Adding Properties to Object

In real life, objects have properties and behaviours, they do not exist without them. In JS, one can create objects with the associated properties or may add them later on as needed and delete them when not needed.

1var obj = {}
2obj.fname = 'Jack' //adding properties using . dot notation
3obj.fname = 'Jill' //it can be updated, it is not a constant
4console.log(obj.fname) // Jill. accessing properties using dot(.)
5console.log(obj['fname']) // Jill.  using square brackets []
6delete obj.fname //deleting properties
7/*Note: you can not delete inherited properties. Every object when created inherit
8    some properties automatically*/
9console.log(obj.fname) //undefined

2.6 Object Properties can be accessed in two ways

To access object properties javaScript provides two ways, either use dot notation . or use square brackets notation[]. Therefore console.log(obj.fname) and console.log(obj['fname']) will produce the same result. When using square brackets notation an expression can be used to access object’s property, provided expression must yield to a property name. For example, if var alias = "fname" then console.log(obj[alias]) will provide same result. Just like other variables behaviour, if a property is not defined, accessing it will return an undefined. And if an attempt is made to get the value of an undefined the compiler will throw TypeError.

1.2.7 Creating Object with defined properties

  • It is not necessary that you first create an empty object and then start adding properties to it. Objects can be created with their existing properties.
1var point = {
2  x: 10,
3  y: 20,
4  draw: function (dx, dy) {
5    console.log('Drawn')
6  }
7}

1.2.8 Why to use square bracket notation

  • It is either used to access or set properties. If you want to use any reserved words as a name of your property or use any special characters or spaces between the property name or any numerical value then you will have to use square brackets notation to access it and enclosed it with quotes, instead of dot notation otherwise it will be flagged as an error. Similarly there will be times when accessing properties dynamically using dot operator would not be possible but square bracket would be used instead.

Another place where you would use the square bracket notation instead of dot is when you do not know the property before hand. This happens often when dealing with web pages and making changes dynamically.

1//var point = { x: 10, y: 20, z axis: 0} // error b/c of space,
2var point = { x: 10, y: 20, 'z axis': 0, '!': 'Exclamation' } // correct
3// To access the properties enclosed with quotes, you can not use dot (.)
4//console.log(point.!);//error
5console.log(point['!']) // Exclamation. o.k
6console.log(point.time) //time is not defined
7console.log(point.time.show) // can not read property of undefined.
8/* TypeError: The above line comes out as a type error, and very common specially in dynamic environment where one tries to invoke some service on an object which does not exist. In the above example the `time` never existed but error is thrown not when it was accessed but when a service is invoked upon it.*/

1.2.9 What are assessor properties

  • Sometimes properties values are not needed or get changed or computed whatever the case, setter provides the way to assign values to properties. You can set the value to the property or provide the setter method to do it, both can not be done at the same time. If setter or getter is used property may be called as assessor properties to differentiate from Data properties.

If a property has both getter and setter method it is called read and write property. To make the property readable only, one can only provide getter method. Similarly if it has only setter it acts as a write only property which makes it unique in a way that Data properties can not be made write only unless ECMAScript-5 attribute write is set to false.

In the example below one Data property start is set to an object as well as Assessor property ( by using the key word get). The name of this property is startPlusPlus, since only getter is used it is only readable. Note the clever technique used here , it is the getter which computes the value of assessor property using given expression. It should be noted that a new property does not exist until it is accessed but its initial value is based on Data property.

1.2.10 Read only assessor property

 1'use strict'
 2var obj = {
 3  start: 0, // Data property
 4  get startPlusPlus() {
 5    return ++this.start
 6  } // Assessor property
 7}
 8obj.startPlusPlus = 10 // in non strict mode ignored silently
 9/*TypeError: Cannot set property startPlusPlus of #<Object> which has only a getter*/
10
11console.log(obj.start) //0
12console.log(obj.startPlusPlus) // 1
13console.log(obj.startPlusPlus) // 2

1.2.11 Read and Write assessor property

 1var obj = {
 2  seed: 0,
 3  get randomNumber() {
 4    return Math.floor(Math.random() * this.seed)
 5  },
 6  set setSeed(num) {
 7    this.seed = num
 8  }
 9}
10obj.setSeed = 256 // This will yield a number between 0 and 255
11console.log(obj.seed) // 256
12console.log(obj.randomNumber) //249
  • It should be noted that get and set may look like functions but they are not. This getter and setter method was provided in ECMAScript-3 API. Now ECMAScript-5 has define property method which is more elegant and provide options which were not possible earlier. For example prior to ECMAScript-5, properties were writable, enumerable and configurable (set to true by default) and there was no way to change this behaviour. Therefore it is better to avoid set/get API of ECMAScrit-3 and use ECMAScript-5 instead.

1.2.12 Like other variables object’s properties have some attributes

When any property is added to JavaScript object it automatically gets some attributes associated with it. Thus property does not have only values but also other attributes namely writeable enumerable, and configurable. These attributes tells if the property can be enumerated ( if enumerable), can be changed ( if writeable ) and these writable and enumerable can be reset ( configurable) that is the status can neither be changed nor the property can be redefine. Thus the default behaviour is shown below

 1// This is the behaviour of Repell shell
 2var x = 10
 3console.log(Object.getOwnPropertyDeiscriptor(global, 'x'))
 4/*{ value: 10, 
 5        writable: true, // can be updated
 6        enumerable: true, // can be enumerated when needed
 7        configurable: false // the above behaviour can not be changed
 8     }*/
 9// This is the behaviour of file.js where global is not a host variable,
10x = 10
11console.log(Object.getOwnPropertyDescriptor(global, 'x'))
12//{ value: 10,writable: true,enumerable: true,configurable: true }
13// This the behaviour when an object is defined whether in file.js or in REPELL
14var o = { y: 23 }
15console.log(Object.getOwnPropertyDescriptor(o, 'y'))
16//{ value: 23,writable: true,enumerable: true, configurable: true }

By default if these attributes are not set, then property can be changed and enumerated and this behaviour can not be changed.To have control over this behaviour, ECMASCript-5 provides a method which can be used to define a property with greater control. Once this function is used to set the value of a property and if others are not set. Then by default they are set to false thus this property can not changed and this behaviour can not altered. Thus you need to pay attention when using this method.

As it is shown above when working within nodeJS environment, a variable defined in an object can be redefine with Object.defineProperty() method which allows its attributes to be changed as discussed in section below.

1var o = { y: 23 } // by default attribute writeable is true
2o.y = 100 // value is updated
3console.log(o.y) // 100
4Object.defineProperty(o, 'y', { writable: false })
5o.y = 200 // fails silently
6console.log(o.y)

1.2.13 Adding properties with ECMAScript-5 approach

  • ECMAScript-5 provides a built in function to set the attributes of the property of the object. There are two functions to define the property one is to use when defining only one property and the other one is when defining more than one.
1var obj = {}
2Object.defineProperty(obj, 'x', { value: 200 })
3console.log(obj.x) //200
4console.log(Object.keys(obj)) // if not define enumerable is false
5obj.x = 300 // can not be done as if not define, writeable is false.
6console.log(obj.x) // 200 remains same
7// it can not be redefined as well

Let’s define all the attributes as shown below.

 1var o = {}
 2Object.defineProperty(o, 'x', {
 3  value: 100,
 4  writable: false,
 5  enumerable: true,
 6  configurable: false
 7})
 8console.log(o.x) // 100.
 9// Since writable is set to false it can not be re assigned any value.
10o.x = 20 // silent failure
11// In strict mode it is flagged as a TypeError: Cannot assign to read only property 'x' of object
12console.log(o.x) // 100
13console.log(Object.keys(o)) // [x] . Since enumerable is true
14// Try to reassign x
15Object.defineProperty(o, 'x', { value: 200, writable: true })
16//TypeError: Cannot redefine property: x
  • The above shows that if a property is defined with configurable : false the same property can not be redefined at all unless when it was being defined, was set to true. It should be noted that, these attributes are set to individual properties and not to the object. Thus other properties can be added and configured.
1var o = {}
2Object.defineProperty(o, 'y', {
3  value: 100,
4  writable: false,
5  configurable: true
6})
7console.log(Object.keys(o)) // []
8Object.defineProperty(o, 'y', { enumerable: true })
9console.log(Object.keys(o)) // [y]

1.2.14 Setting more than one property Object.defineProperties()

 1var obj = {}
 2console.log(obj)
 3Object.defineProperties(obj, {
 4  x: { value: 2, writable: true, configurable: true },
 5  y: { value: 3, writable: true, configurable: true },
 6  r: { value: 10, writable: false, configurable: false }
 7})
 8console.log(Object.keys(obj)) // []. empty
 9console.log(obj.propertyIsEnumerable('x')) // false
10// Following loop will not run because condition is not true.
11for (var prop in obj) {
12  console.log('properties are ' + prop)
13}
14// Either change the attribute individually
15Object.defineProperty(obj, 'x', { value: 20, enumerable: true })
16// Or use the following to see the property only
17console.log(Object.getOwnPropertyNames(obj)) //[ 'x', 'y', 'r' ]
18console.log(Object.getOwnPropertyNames(obj).sort()) //[ 'r', 'x', 'y' ]

1.3 Object Attributes

  • Not only object’s properties have attribute but object itself has attributes which defines its behaviour. These attributes are prototype,class and extensible.

1.3.1 Prototype Attribute of an Object

  • ECMAScript-5 provides a way to get object’s prototype by using Object.getPrototypeOf(target) method. Before ECMAScript-5 it was made possible by using the object inherited property __proto__ or using o.constructor.prototype for the object created by a given prototype Object.create(fromP) method. To find out if one object is prototype of the other or is part of the prototype chain a.isPrototypeOf(b) ( to find out if “a” is prototype of “b”) is used.
 1function fn() {
 2  var age = 10
 3}
 4var a = { size: 10 } // a gets default prototype
 5var b = Object.create(a) // b is created from prototype a
 6var c = Object.create(fn) // c is created from prototype fn
 7console.log(Object.getPrototypeOf(a)) // {}
 8console.log(Object.getPrototypeOf(b)) // {size:10}
 9console.log(Object.getPrototypeOf(c)) // [Function fn]
10
11console.log(Object.getPrototypeOf(a) === Object.getPrototypeOf(b)) // false
12console.log(Object.getPrototypeOf(b) === Object.getPrototypeOf(c)) // false
13console.log(Object.getPrototypeOf(c) === Object.getPrototypeOf(a)) // false
14
15//Constructor Prototype

1.3.2 Class Attribute

  • Since JS never had any classes or class syntax before ECMAScript-5. Thus more attention to be paid here. In JS the user type is created from the constructor function and this is the function which acts as class of its type.
1function Animal() {
2  var breath = true
3}
4var rabbit = new Animal()
5console.log(rabbit)

1.3.3 Extensible Attribute

If the properties of the object can be added to the object after its creation the object is said to be extensible. All built in and user defined objects are implicitly extensible unless they are explicitly made non extensible. To make it non extensible, it can be passed to Object.preventExtensions() once is it non extensible it locks down the object into a locked state and prevent it from the outside tampering.

 1var o = {} // By default it is extensible
 2o.x = 10
 3console.log(o) // { x: 10}
 4Object.preventExtensions(o) //can not be extended
 5o.y = 10 // fails silently , y is not added
 6console.log(o) // Still { x: 10}
 7// property is still configurable and can be changed and deleted
 8o.x = 100
 9console.log(o) // { x: 100}
10delete o.x // it can still be deleted
11console.log(o)
12o.x = 20 // fails silently because it can not be extended.
13console.log(o)

Though the above code prevent the object to be extended but already existing properties can still be set and deleted. To make an object non extensible and as well as make its properties non configurable another method Object.seal() can be used instead of the above as shown below. Making object properties non configurable means that whatever attributes the properties are set with can not be reset. If a property is set with writable true, it can cont be made false because it can not be re configured.

 1var o = { x: 10, y: 20 }
 2Object.seal(o) // Making it sealed
 3o.z = 100 // fails silently
 4delete o.x // fails silently
 5console.log(o)
 6// changing the value of properties
 7o.x = 1000
 8o.y = 898 //if it was allowed before,will still be allowed
 9console.log(o) // { x: 1000, y:898}
10// Properties can also be reset because before sealing the object
11// their writable state was set to true
12console.log(Object.isExtensible(o)) // false
13console.log(Object.isSealed(o)) // true
14console.log(Object.isFrozen(o)) // false

Object which needs to be provided high level protection can be frozen by using Object.freeze(o). If an object is made frozen, it automatically prevents its extension and makes it non configurable but at the same time it also makes its properties read only. To see if the object is frozen one can use Object.isFrozen() just like other method used to see if the object is sealed Object.isSealed(o) or extensible. Object.isExtensible(o)

1var o = { x: 20, y: 30 }
2Object.freeze(o)
3console.log(Object.isFrozen(o)) //true
4// All below commands fails silently
5o.x = 100 // can not be reset
6delete o.y // can not be deleted
7o.z = 200 // new properties can not be added
8console.log(o) // {x:20, y:30}

Object main services and static methods

All JS objects by default share services from their corresponding prototype. These services are mainly methods which are used by newly created instance. An instance of Array class gets to share everything from the Array.prototype and being an object it also get to share from Object.prototype and so on until the prototype inheritance reaches the point where the prototype becomes the null. Apart from these shared methods, a programmer often use static method define on Object constructor which are given below.

1var arrayProp = Object.getOwnPropertyNames(Object)
2var fun = arrayProp.filter(function (element) {
3  return typeof Object[element] === 'function'
4})
5console.log(JSON.stringify(fun))
6/* ["assign","create","freeze","getOwnPropertyDescriptor","getOwnPropertyNames","getOwnPropertySymbols","is","isExtensible","isFrozen","isSealed","keys","preventExtensions","seal","defineProperty","defineProperties","getPrototypeOf","setPrototypeOf"]
7 */

When discussing about shared services from the prototype object, there are some methods which can be over ridden to provide object specific details. For example toString() method which gets shared from Object.prototype when applied to any object does not show much. Note whenever you apply concatenating operator + to something which is not an string JS automatically apply toString() function to convert it string.

1var o = { x: 1, y: 2 }
2console.log(o.toString()) // [object Object]
3console.log(o) //{x: 1, y: 2}
4console.log(o + '') // [object Object]
5console.log(JSON.stringify(o)) //{"x":1,"y":2}

Because there is no useful information provided by the toString() method, the other classes defines their own behaviour of toString() method. For example the Array , Date and Function classes over rides this function to provide useful information as shown below.

1var y = [123, 4567] // An array object
2console.log(y) // [123,4567]
3console.log(y.toString()) // 123,4567
4var fn = function () {
5  console.log('I am a function')
6}
7console.log(fn) // [Function: fn]
8console.log(fn + '') // function(){.....}

Creating objects with Object constructor i.e., using new operator

Programmers who come from class based object oriented background often get puzzled with the way JavaScript works. For example it is the very basis of Object oriented programming to instantiate the object in order to create it from its class. And to do so they are programmed to use class constructor with the help of new operator. In JavaScript the following method is used to create either user defined or pre defined objects with new operator. They are known as built in constructor.

 1// User defined object
 2var point = new Object() //same as {}
 3point.x = 10
 4point[y] = 20
 5console.log(point)
 6// Predefined object
 7var myObject = new Object() // same as creating from literals {}
 8var grid = new Array() //same as creating from square brackets []
 9var today = new Date() //No short cut present
10var word = new RegExp('JavaScript') //No short cut

No matter which book or article you read, there will be an advice “Don’t use new” to create an object, use object literal {} instead.

Both methods do the same job as long as you are not doing any special computation which requires memory optimization. Keep in mind with object literal no instantiation is required and your code is optimized as far as less typing is concerned, on the contrary with new more typing is involved and object instantiation is performed.

Objects have behaviour

Objects not only have some properties ( object’s attributes) attached to them but they contain methods. Functions in JS, when defined in object are called methods ( and in all other languages too). A function’s typical job is to do something (compute some values) and return the result. This can be understood as objects’ behaviour. In JavaScript object’s properties are assigned to functions to exhibit the behaviour of an object and known as methods.

 1var point = {
 2  x: 10,
 3  y: 20,
 4  move: function () {
 5    console.log('point has moved')
 6  }
 7}
 8// invoking a function
 9point.move()
10//or
11point['move']()

Calling or Invoking objects’ methods

In above code apart from x and y the word move is also a property of the object but since move property is assigned an anonymous function. It behaves like function identifier and regarded as object’s method. As we have learned before to execute this method we will have to use trailing brackets when invoking a function. Thus point.move() will invoke this function. It will be interesting to note that just like the other way of accessing the property i.e., using square brackets notion, you can also use square bracket notation to invoke the method. After all it is a legal property of this object. To do so, point['move']() will be used. But it is not the accepted practise among programmers. Hence be aware of what can be done and what is accepted as a good practice.

Note: When a method is invoked upon on any object. A key word this is set/given to that method by providing it a way to access objects’ variables/properties.

Accessing object’s properties from within its own method

When a function is defined in an object it can only be invoked through that object. Therefore inside the definition of the function referring to the same object needs to be done explicitly by using the object name or with the keyword this which is given to function when it is invoked with respect to its execution context.

 1var point = {
 2  x: 10,
 3  y: 20,
 4  move: function () {
 5    //console.log(x,y) // error x and y are not accessible here
 6    console.log('x  is ' + point.x + ' while y is ' + point.y)
 7    console.log('x is ' + this.x + ' while y is ' + this.y)
 8  }
 9}
10point.move()
11console.log(point.x) // both x and y are public members
12console.log(point.y)

Object’s properties are mutable

In the above code the values of x and y are accessible to everybody (public ), what it means that a user can access the values using the object without having to worry about anything. Not only the values can be accessed but changed easily as done here. In fact, the mutability of any object's properties reflects the objects’ change in state.

 1var point = {
 2  x: 10,
 3  y: 20,
 4  move: function (dx, dy) {
 5    this.x = this.x + dx
 6    this.y = this.y + dy
 7    console.log('new x is ' + this.x + ' while new y is ' + this.y)
 8  },
 9  deleteThem: function () {
10    delete this.x
11    delete this.y
12    console.log('new x is ' + this.x + ' while new y is ' + this.y)
13  }
14}
15point.move(100, 10) // object state is changed
16point.deleteThem() // object state is changed

Object can contain other objects as its properties

It is very common in JavaScript code to see an object containing another object for one or the other reasons. It may be that they have containing relationship or the programmer has chosen this design. Let say I have a car that has an alarm. I decide to have an alarm property of the car as an object.

 1var car = {
 2  make: 'Toyota',
 3  model: 'Prius',
 4  // alarm is a property of a car which itself is an object
 5  alarm: { type: 'standard', isModified: false, isOn: true },
 6  starts: function () {
 7    if (this.alarm.isOn) {
 8      console.log('starting')
 9    } else {
10      console.log('can not start')
11    }
12  }
13}
14car.starts() //starting
15car.alarm.isOn = false // car state is changed
16car.starts() // can not start

Enumerating object’s properties

Often you need to see what is present in concerned objects. JavaScript provides a built in function known as for...in loop . It loops through the given object and its prototype chain and returns properties names along with their values in a string format. A very handy function to see what is present in your object. There are some other functions which we will discuss later on.

1var courseNames = { x: 1, y: 2, z: 11 }
2for (var prop in courseNames) {
3  console.log('courseNames.' + prop + ' =' + courseNames[prop])
4}

Since there was no prototype chain the function returns not only the property names but associated values of the target object only. When retrieving with for...inloop it also retrieves methods and the other objects from the target object therefore you need to write code to filter them out as done following.

 1var courseNames = {
 2  x: 1,
 3  y: 2,
 4  z: 11,
 5  anyFunction: function () {},
 6  emptyObject: {}
 7}
 8var propName // you can add code to filter objects as well if you need
 9for (propName in courseNames) {
10  if (typeof courseNames[propName] !== 'function') {
11    console.log(courseNames[propName])
12  }
13}

In order to filter any prototype values use hasOwnPropertyNames() in your logic

When enumerating which function to use

If the object’s property enumerable attribute is set to true ( thus enumerable) it can be enumerated using either for...inloop or Object.key(obj) method. The difference between them is that for...in loop enumerates properties in the prototype chains as well ( if there is any ) while Object.keys() method only returns the properties of object’s own enumerable properties( only enumerable ).

 1var courseNames = {
 2  x: 1,
 3  y: 2,
 4  z: 11,
 5  anyFunction: function () {},
 6  emptyObject: {}
 7}
 8// Use of Object.keys(obj) function
 9console.log(Object.keys(courseNames))
10// will return [ 'x', 'y', 'z', 'anyFunction', 'emptyObject' ]

To see if the property is enumerable or not use propertyIsEnumerable(prop) function on the object whose property attribute is to be checked.

 1var courseNames = {
 2  x: 1,
 3  y: 2,
 4  z: 11,
 5  anyFunction: function () {},
 6  emptyObject: {}
 7}
 8console.log(courseNames.propertyIsEnumerable('x')) // true
 9console.log(courseNames.propertyIsEnumerable('abc')) // false
10// Note the use of quotation marks, the property name must be quoted

There are other functions which can provide help about properties and their associated attributes provided by EcamaScript-6 which we will be using later on like getOwnPropertyDiscriptro() function and getOwnPropertyNames(obj)

Looking for a particular property

Often there is a case when you only want to look for a unique property to make sure whether it is present or not in your object. There are different approaches present some are discussed below. The conventional method would be to write a loop and go through each and every property and comparing the one you want.

Be clear what exactly you are comparing is it a property key or its value.

 1var courseNames = { Ms012: 'Cognitive Science', Bs310: 'Physics' }
 2//checking through property's value
 3for (var prop in courseNames) {
 4  if (courseNames[prop] === 'Cognitive Science') {
 5    console.log('Yes ' + courseNames[prop] + ' is present')
 6  }
 7}
 8//checking through property's key
 9for (var prop in courseNames) {
10  if (prop === 'Bs310') {
11    console.log('Yes ' + prop + ' is present')
12  }
13}

The above does the job but as we said earlier there are other more elegant approaches present. Though there are subtle differences but both does the same job.

1var courseNames = { Ms012: 'Cognitive Science', Bs310: 'Physics' }
2if ('Ms012' in courseNames) {
3  console.log('Yes it is present')
4}
5//or
6if (courseNames.hasOwnProperty('Bs310')) {
7  console.log('Yes it is also present')
8}

What goes behind Object creation

When an object is created with its literal {} notation or using new Object() constructor, only and only one instance of a specific type is created. And there is no other object like it. Thus var o1 = {x:1}; and var o2 = {x:1}; are not same at all. They are only equal to themselves.

1var o1 = { x: 1 }
2var o2 = { x: 1 }
3console.log(01 == 02) //false
4console.log(01 === 02) //false
5console.log(01 == 01) //true
6console.log(02 === 02) //true

In memory they are two separate objects holding different spaces. The object identifier o1 and o2 both are basically the pointers to their respective objects.

 1
 2       {x:1}                           {x:1}
 3    ++++++++++                      ++++++++++
 4    |        |                      |        |
 5    |        |                      |        |
 6    ++++++++++                      ++++++++++
 7      AFE12B                          FEBC41
 8        ^                               ^
 9        |                               |
10        |                               |
11        o1                              o2
  • Since when object is created, the question comes in mind how to delete them. JavaScript is a dynamic language and takes this responsibility itself. It is the job of the garbage collector to delete any dangling object which has no reference to it. But if you want to release memory you may assign it to a nullvalue but it does not guarantee an immediate release of memory. There are some other techniques used to delete the memory.

Note: You can not delete object using delete operator as you would delete any variable or any object’s property if it is deletable.

1delete o1 // not allowed and not possible
2delete o1.x // allowed and possible

Object testifies itself

When an object is created, it also get another object created by the system that works as a prototype of newly created object. The newly created object not only has access to its own properties but also the properties of its prototype. If a newly created object is searched for a property that it can not find, its prototype is searched and the search goes on until the top of chain is reached. This secrete internal link of invisible objects is known as prototype chain.

For example, in above case when o1 is created with one property but it automatically inherits ( gets available ) some properties and methods from a special object named prototype which is defined in Object as its one of the properties thus can be accessed as Object.prototype.

To get more detail about this special object which a newly created object receive you may take the help of of its own provided methods, such as toSring , to String() , getPrototypeOf() and so on. These available methods ( or some may call it services) and others are always available to the object you create to ease your work as shown below

 1var stomach = {}
 2var apple = { juicy: true }
 3var banana = new Object({ juicy: false })
 4var pear = Object() // forget to write new
 5console.log(Object.getPrototypeOf(stomach)) // {}
 6console.log(Object.getPrototypeOf(apple)) // {}
 7console.log(Object.getPrototypeOf(banana)) // {}
 8console.log(Object.getPrototypeOf(pear)) // {}
 9console.log(apple.constructor) //Object
10console.log(banana.constructor) //Object
11console.log(stomach.constructor) //Object
12console.log(pear.constructor) //Object
13//you may use typeof operator as well
14console.log(typeof stomach) // object
15console.log(typeof stomach.prototype) //

The code above testifies few things:

  1. Objects created with a literal {} or with a constructor new Object() also get a prototype object {} to share its behaviour.
  2. They all are created from the same constructor.
  3. If you forget to write new before built-in constructor it is taken care of.
  4. Objects created by user get number of services available to it automatically by design. These services are exposed by the Object.prototype object { }.
  5. Two internal links are established among user defined object and the object that provides services and the object that creates it.

It is important to understand that if this internal link is lost your program may not behave the way it is expected. The constructor property points to the constructor that creates it. If you write your own constructor function then this property will point to the user defined constructor. Let see this whole in figure given below

 1     var anObject = {}; or var anObject = new Object()
 2
 3                    prototype property of Object
 4                            |               |
 5      Object()              |               V
 6    =============           v           ==========
 7    |constructor | Object.prototype--->|prototype |- constructor:
 8    |   object   |                     |  object  |- __proto__:
 9    =============                       ========== -        |
10          ^                                 ^      -hasOwnProperty()
11          |                                 |      -isPrototypeOf()
12          |                                 |       -.....  |
13          |                                 |       -.....  |
14          |                                 |               |
15          |                                 |       services shared
16    anObject.constructor                anObject._proto_
17                        ==========
18                        |anObject |
19                        ==========

Assigning objects to other variables

Once an object is created it can be assigned to any other variable. In JavaScript this assignment is known as shallow copying in object oriented programming. Thus following code does not create a new object but another pointer to the same object already present in the memory.

 1    var o3 = o1;
 2    console.log("Are they equal " + ( o3 === o1));
 3    o2 = null;      //o2 no longer points out to previous space in memory
 4                    // it has been de referenced
 5
 6                      {x:1}
 7                    ++++++++++
 8        o1 ----->   |        |      o2 ---> null
 9        o3 ----->   |        |
10                    ++++++++++
11                     AFE12B

JavaScript Objects are mutable and manipulated by reference

It is clear from the above example that the objects are passed by reference when they are assigned to new variables or passed to any function. Passing by reference put more responsibility upon the user. If an object gets changed by one reference the change is shown by others immediately.

1var o1 = { x: 1 },
2  o2 = { x: 1 },
3  o3 = { x: 1 } // They are all different objects
4// but now they are going to refer same object
5var o1 = (o2 = o3 = { x: 1 }) // All referring to same object
6// the original objects memory taken by o2 and o3 are deleted automatically ( ??)

Object.prototype and Prototype object are different things

For new comers the term prototype becomes confusing. In classed based Object Oriented languages, class provides the blue print or die for objects of same type to be created. These objects are known as instances of a class and they share the services provided by the class. In JavaScript since there has been no concept of classes until recently when ES6 has come out in the market.

When programmer started using c and other contemporary languages twenty years ago they did not have thousand lines of code already written and ready to be used available for their programme. They had to write everything from scratch. But then came along Class based Object Oriented programming providing libraries and other facilities to be used without re inventing the wheel. Most of the time the code reuse was achieved by having the top level Object already written for the user which would expose commonly used services for the user defined newly objects. And this technique was known as inheritance which involved the concept of classing and sub classing by way of inheriting properties from their super class based on the notion of having a relation known as is-a or a kind of. For example, rabbit is an animal so is a frog and others. They may have same attributes and some would differ and so on. Hence the idea was to keep the top class more generic and subclasses specific.

Since JavaScript was not at all an Object Oriented language, this is-a relation was achieved using techniques called composition and containment as opposed to inheritance. Therefore the term prototype was used to indicate the top most class which types of object were needed. In JavaScirpt When you create any object, the language provides a prototype object to the new object to share the services from. This is a default behaviour of the JS. To manipulate the new object JS allows you to use a global object called Object, it should be interested to know that the prototype object which were given to you to use the services is also defined as property of this Object thus written like Object.prototype. Having explained this, it is important to understand that when a user wants to create a class ( since JavaScript never provide the facility to write classes), it was left to define their own constructor function which acted like super class and came to be known as the Prototype for creating the same type of objects.

Object.prototype means that the Object has a property named prototype which itself is an object. And its properties gets inherited automatically by any object created by either object literal or Object constructor. { we will discuss this automatic inheritance later on }

A rough shape of Object

 1   Object = {
 2        .....//other properties
 3        .....
 4        prototype: {
 5            constructor:....
 6            _proto_:.....
 7            .....
 8        }
 9            ....//other methods
10            hasOwnProperty: function(property){.....}
11            isPrototypeOf:  function() {......}
12            propertyIsEnumerable:   function(){......}
13            toString:   function() {.....}
14            ......
15   }

Object.prototype itself, does not inherit any property from any object. To see if it is true or not simply type console.log(Object.getPrototypeOf(Object.prototype)); and you will get the null answer.

All built in constructors first inherit properties from their corresponding built in constructor and then from Object.prototype as well. This inheritance is known as prototype chain.

All built in objects like Array , Date , RegExp etc are also type of Objectthat is they descend from top most object. Similarly they all get to share code from their corresponding prototype which in turns also inherit code from object prototype. For example new Date() and new Array() first inherit properties from Date.prototype and from Array.prototype respectively but also inherit properties from Object.prototype too.

To find out the exact constructor of a newly created object we can use constructor as inherited property, Object.prototype.constructor which returns the function constructor that creates given object’s prototype. In other words when a new object is created it inherits this property which points to the constructor which created the new object.

 1var o1 = {},
 2  today = new Date(),
 3  grid = new Array()
 4var n = new Object(1)
 5
 6console.log('o1 is created  by ' + o1.constructor) // function Object()
 7console.log('today is created  by ' + today.constructor) //function Date()
 8console.log('grid is created  by ' + grid.constructor) //function Array()
 9
10// Another way of testing would be
11if (n.constructor === Number) {
12  console.log('n is created  by ' + n.constructor) //function Number()
13}
14// Even a function in JavaScript is created using Function() constructor
15var f = function () {}
16if (f.constructor === Function) console.log('f is created by ' + f.constructor)

Creating Object with Constructor function

Creating objects with object literal or Object constructor both provides a way to create a single object pattern. What it means that you are only able to create only one object of a particular type. To create multiple objects of a same type you need to use Constructor function. That is to create as many instances as you want from a blue print.

In OOP you can write a class and create many instances from that blue print. In JavaScript making different instances from its prototype is achieved using a technique called creating objects with Constructor Function. The following code writes a Constructor function so that multiple instances of this function can be created. This is an interface like a class providing a constructor pattern to create same type of objects.

1// Constructor function,a prototype for other objects, it acts like a class
2function Animal(itsName) {
3  //note Animal with Capital A to identify as a CTOR
4  this.name = itsName
5}
6//Create different instances of Animal using new operator from its prototype
7var rabbit = new Animal('Bunny')
8var cat = new Animal('Nimy')

The code var rabbit = new Animal("Bunny") is just like creating an instance from its class in class based Object Oriented Languages. But here we know that Animal is not a class but a mere function declaration. In JavaScript it is one of the ways to create multiple instances of a same object. It is either rabbit or cat both have their own data and do not share their state from each other. Thus the code console.log(rabbit.name); will yield to “Bunny” while the code console.log(cat.name); will yield to “Nimy”. If you like to add a variable which gets available to all instances of the class then you have to make it a class variable not the instance variable or what is known as static variable. A static variable is shared among all instances of a same class and can only be invoked by the class name itself. It can not be invoked by the instance of that class. A class can not only have static properties but can also have static methods which can only be invoked by the class itself. The example of static methods are Object class methods most of them are only static and can only be used by the Object itself and not by the instances of the Object class. Object.create(),Object.getPrototypeOf() are just two examples of static object defined on Object.

 1function Animal(itsName) {
 2  Animal.counter = (Animal.counter || 0) + 1
 3  this.name = itsName
 4}
 5console.log(Animal.counter) // undefined
 6var rabbit = new Animal('Bunny')
 7console.log(Animal.counter) // 1
 8var cat = new Animal('Nimmy')
 9console.log(Animal.counter) //2
10condole.log(rabbit.counter) // undefined

Though the above is a very simple example yet explains the point. You can also add functions to the constructor function.

Adding properties

It is important to note that member variables of an object known as properties ( can either be a simple property or a method) can be added to an individual object or to objects’ prototype.

Adding properties and methods to individual objects

 1function Animal(itsName) {
 2  this.name = itsName
 3}
 4var rabbit = new Animal('Bunny')
 5rabbit.maxAge = 18
 6
 7var dog = new Animal('Wosh')
 8dog.maxAge = 16
 9dog.barks = function () {
10  return this.name + ' says Hello'
11}
12
13var cow = new Animal('mo')
14cow.maxAge = 20
15cow.milks = function () {
16  return 'Hi, it is delicious'
17}
18
19console.log(rabbit) //{ name: 'Bunny', maxAge: 18 }
20console.log(dog) //{ name: 'Wosh', maxAge: 16, barks: [Function] }
21console.log(cow) //{ name: 'mo', maxAge: 20, milks: [Function] }
22console.log(cow.milks()) //Hi, it is delicious
23console.log(dog.barks()) //Wosh says Hello

In above code the property maxAge which is shared by all instances should be added directly to the constructor function. So it is shared among all instances. However there are some situations where a new property is needed to be added dynamically in that case it is added to prototype object instead of adding separately to each object.

Adding properties to prototype object

In order to add a property or a method to the function object, JavaScript allows a built-in property to be used to achieve this task. This property is called prototype and is only available to the function object and not to the object. Thus the code Animal.prototype.maxAge will add property maxAge to the prototype object. And in this case the prototype object is the default prototype object Object.prototype.

 1function Animal(itsName) {
 2  this.name = itsName
 3}
 4Animal.prototype.maxAge
 5var rabbit = new Animal('Bunny')
 6rabbit.maxAge = 18
 7
 8var dog = new Animal('Wosh')
 9dog.maxAge = 16
10
11var cow = new Animal('Mo')
12
13console.log(rabbit)
14console.log(dog)
15console.log(cow)

Note: Adding property to a prototype object gets available to be used by all instances of Constructor function but it does not become the member of a constructor function. To add a new member to constructor function it has to be added manually. You can not add a new property to a constructor function by Animal.newproperty. As Animal is not an object.

How CTOR function( the prototype ) initialized

  • The code var cat = new Animal("Nimy") when executed does the following things.
  1. It creates an empty object and keep a reference on it by using a reserved word this.
  2. An internal link is established between this newly created object and Object.prototype so that it inherits properties from Object.prototype making all properties and methods available to the newly created object.
  3. It also sets the constructor property of the Object.prototype to Animal
  4. This object is returned implicitly if no other object is returned explicitly from this constructor.

This newly created object now becomes an instance of an Animal which you have defined.

Public and Private members & use of this in Constructor function

Members variables which can be accessed directly by the instance of the class after they have been instantiated are regarded as public members. By design objects have to provide public methods which can be invoked upon the object and inside the implementation of the object member variables are accessed keeping them private. In Js when creating an object with constructor function, private variable are written using var keyword which provides them function scope making them impossible to access from the instance variable outside the constructor function.

 1//file-name:13.js
 2function Animal(itsName) {
 3  this.name = itsName //public member
 4  var breathes = true //private member
 5  var age = 1
 6  this.isAlive = function () {
 7    //public member
 8    return breathes === true ? 'yes' : 'no'
 9  }
10  var changeAge = function (x) {
11    //private member
12    age = +x
13  }
14}
15var rabbit = new Animal('Bunny') // A new object is created and returned
16console.log(rabbit.name) // allowed , public members
17console.log(rabbit.breathes) //undefined, private members
18console.log(rabbit.isAlive()) //allowed
19rabbit.changeAge(1) //error ;not allowed, it is not visible here

From the above it should be clear that all local variables or functions defined using var key words make them private members. While those defined by this keyword become public members.

Can the new instance testifies itself

The instance of Animal which is just created and now referenced by rabbit should be able to give some detail about itself if it is an instance of Animal. To get those details we take the help from functions that it inherits implicitly as well as with the available operators.

1//using inherited methods, a robust way of checking
2console.log(rabbit.constructor) // [Function:Animal]
3console.log(Object.getPrototypeOf(rabbit)) //Animal {}
4//using operators , can be deceptive in some situations
5console.log(typeof rabbit) //object
6console.log(rabbit instanceof Animal) //true

The above code testifies that the object created and returned is the right one you intended.

Forget to use new! face the music

Imagine you create an instance of Animal and forget to use the new operator var cat = Animal("Nimmy") . There will be no error nor any warning but your programme will not behave the way you would want. Therefore it is best practice to use code pattern . A code pattern is just a unique way of writing some code which makes/forces code do what it is supposed to do despite lacking of strongly typed language. Now what happens if the new is not typed.

1var cat = Animal('Nimmy')
2console.log(cat.constructor) // error: cat is not an object
3console.log(Object.getPrototypeOf(cat)) //error
4console.log(typeof cat) //undefined
5console.log(cat instanceof Animal) //error

Without the use of new operator before the constructor function no object gets created thus the use of inherited properties results in error. The members of Animal constructor function does not get bind to this and become the property of the global object. It is just like variables declared inside the function without the keyword var are regarded as implied global. Thus can be accessed using global.name , window.name or anything else depending upon the host environment. To see what exactly this refers to you can add this code in your programme console.log(this).

Why not flag it as an error

Forgetting to write new, raises issues which were not anticipated and tackled when constructor function was written. In an ideal situation an error should have been raised warning the mistake but it does not happen. To tackle this problem there has been many ways and one of them is to use code pattern while the other is to raise the error using JavaScript provided throw. Using code pattern or any other approach is a way to tackle the problem but the language itself provide the safe mechanism and urges programmer to use it which is known as use strict. We will talk about it coming topic

Tackling issue with Code Pattern

To make sure that in case of forgetting to write new your code behaves correctly. You need to change the code of constructor function by explicitly returning an object as done below.

 1    //file-name:13-1.js
 2   function Animal(itsName) {
 3    var temp = {}
 4    temp.name = itsName;
 5    return temp
 6   }
 7   var dog = new Animal("wof");
 8
 9    console.log(dog.constructor);   //[Function:Object]
10    console.log(Object.getPrototypeOf(dog));// {}
11    console.log(typeof dog);    //object
12    console.log(dog instance of Animal); // false

The above make sure that an object is always created and returned. It may be interesting to note that the convention of writing this pattern uses a that identifier instead of temp, but you may use whatever you like. It is also not necessary to return a named object you may return an object using its literal as shown below.

1    function Animal(itsName){
2        return {
3            name: itsName;
4        }
5    }

Problem with the code pattern approach

Though code pattern seem to solve the issue encountered by forgetting to write new but raises others concern. The whole chemistry of our idea to be able to create multiple instances from a prototype is changed for the following reasons;

  • First of all the object returned is not an instance of an Animal but a generic object.
  • Its prototype is not Animal but an empty object {}
  • Its constructor is Object not Animal any more.

In short it all happens because the code pattern did not do the job fully. it did create an object took care of problem arising from the issue of forgetting to write new but failed to provide the prototype link b/w newly created object and the object that it inherits from.

To fix this issue in constructor function, a logic is added to check if an executing context is an instance or not, if not we call it with a new operator that is a self execution . Thus new constructor function would look like as shown below.

1function Animal(itsName) {
2  if (!(this instanceof Animal)) return new Animal(itsName) // execute itself
3  this.name = itsName
4}

The above approach seems to work fine even if we forget to write new operator with constructor function. This technique is known as scope-safe and adopted internally by most built in constructor to first see if the user has called the constructor using new operator or not, otherwise it executes itself. The above code can also use the arguments.callee but it is not preferred and may be remove from new versions.

Tackle this issue by raising as an error

Another way to tackle this problem of forgetting to write new operator is to nip the evil in the bud, approach. A logic is provided in your constructor to see if it is invoked with new or not if not raise an error as done below.

1function Animal(itsName) {
2  if (!(this instanceof Animal)) throw new Error('call with new keyword')
3
4  this.name = itsName
5}

A Real World example of a constructor function

MetalSmith is a static web site generator which exposes a function as a module named metalsmith. The declaration of this function is shown below.

 1module.exports = Metalsmith
 2
 3/**
 4 * Initialize a new `Metalsmith` builder with a working `directory`.
 5 *
 6 * @param {String} directory
 7 */
 8
 9function Metalsmith(directory) {
10  if (!(this instanceof Metalsmith)) return new Metalsmith(directory)
11  assert(directory, 'You must pass a working directory path.')
12  this.plugins = []
13  this.ignores = []
14  this.directory(directory)
15  this.metadata({})
16  this.source('src')
17  this.destination('build')
18  this.concurrency(Infinity)
19  this.clean(true)
20  this.frontmatter(true)
21}
22
23// only plugins and ignores are properties which are assigned an empty array the rest are functions. These functions are declared somewhere in the programme

Adding methods to constructor function

Once you overcome the problem of creating the constructor function, you are through to creating different instances from this prototype. Every instance you create from this blue print gets its own copy of members variable. Say if you create ten instances of from Animal constructor. Each instance gets its own copy of members ( variables and functions ).

There is nothing wrong with this in fact this is exactly what we wanted to achieve . To be able to create multiple instances of a same type. However we have to reconsider the issue of dealing with members which are not ordinary variables but functions added as are part of the constructor function. The reason being that ordinary variables and functions differ in many ways . Every time a function is created there are more overheads to be considered as compared to ordinary variables and this can lead to memory optimization issues.

Using prototype property to add functionality / Augmenting Built-in Objects through prototype

First of all be clear that JavaScript provides you many built in constructor of different type to start creating your objects without writing your own from the scratch. These built in objects behave like a die ( a moulding die ) or commonly knowns as blue print or prototype. In addition to creating the object from this constructor, JavaScirpt also allows you to add different services which may not be provided by built in constructor. When you add extra functionality into built in object’s prototype, the object is said to be augmented.

 1var pen = {}
 2pen.writes() //error write is neither a member of pen nor its prototype
 3
 4// get the prototype of pen object and add this function to it.
 5Object.getPrototypeOf(pen).writes = function () {
 6  console.log('It works')
 7}
 8//call this function on pen
 9pen.writes() // It works
10// create a new object with the same prototype {} and use this function.
11var pencil = {}
12pencil.writes() // It works

Thus adding any functionality to the prototype of any object gets available to all its instances hence sharing the same code for all instances. In order to add any functionality to objects’ prototype ( its die / blue print ). Javascript exposes an object through a member of Object also named as prototype which itself is an object. Therefore in the code above it is not necessary to call the function Object.getPrototypeOf(object) on any object but to use the prototype property which is available to all objects.

1// Adding functionality to built in Date object
2Date.prototype.showAlienDate = function () {
3  console.log('☺♂↓☺☻•☻')
4}
5var d1 = new Date()
6d1.showAlienDate() // it works

Not only you can enhance the functionality of built in object but also to any user defined object using its Constructor.

 1//file-name:chap-02-02.js
 2function Animal(itsName) {
 3  this.name = itsName //public member
 4}
 5var rat = new Animal('Gerry')
 6console.log(Animal.prototype) //
 7
 8// Adding methods to prototype
 9Animal.prototype.move = function (steps) {
10  console.log('It has moved ' + steps + ' steps')
11}

By doing this we make sure that method moves get added to the prototype Animal and all instances can use it safely. Not to mention that there is nothing stopping you to add new properties to your object dynamically taking help from prototype object. Thus Animal.prototype.age = 0 ; will add a new property to an existing object.

It should be noted that when adding functions to prototype, it can be done safely in the following way only exposing the interface as shown below. This technique is know as revealing prototype pattern

 1var OrganiteModel = function () {
 2  this.shape = 'pyramid'
 3  this.energyType = 'Scalar'
 4  this.use = 'nonCommercial'
 5}
 6
 7// Adding prototype
 8OrganiteModel.prototype = (function () {
 9  var on = function () {
10    console.log('It has been turned on')
11  }
12  var off = function () {
13    console.log('It is off!')
14  }
15  //return
16  return {
17    turnOrganiteOn: on,
18    turnOrganiteOff: off
19  }
20})()
21var myOrganite = new OrganiteModel()
22myOrganite.turnOrganiteOn() //It has been turned on
23myOrganite.turnOrganiteOff() //It is off!

Use of helper functions defined outside the constructor to access properties

It is possible to create any function outside the constructor which can access object properties. Since these functions live in global context can easily start to create problems with other functions. This situation is known as polluting the Global Namespace which may results eventually in conflicting with other names. Secondly, it violets the basic principle of encapsulation. Your object should provide its services not an outsider thus also regarded as anti pattern as shown below.

 1    function Animal(itsName){
 2        this.name = itsName;        //public member
 3    }
 4    // new instance is created
 5    var rat = new Animal("Gerry");
 6    // function to access object properties
 7    function showName(){
 8        console.log(rat.name);
 9    }
10    showName():

Methods defined in constructor

The above function can easily be defined inside the object constructor making it more safe from any possible conflicts and adhering to Object Oriented principles as follows.

1function Animal(itsName) {
2  this.name = itsName
3  this.showName = function () {
4    console.log(this.name)
5  }
6}
7var rat = new Animal('Gerry')
8rat.showName()

It should be noted that if a same function is added to the prototype ( name conflict) then only method defined on an object that is in constructor gets called. JavaScript will not throw an error if you use the same name as done in the constructor. A method is invoked on an object, it first look through its instance function list, if it finds it there, fine the instance function will be called . If it does not find there it will look into its prototype. See the example below

 1function Foo() {
 2  this.instanceFunction = function () {
 3    console.log('This is an instance function')
 4  }
 5}
 6//
 7Foo.prototype.instanceFunction = function () {
 8  console.log("This is a prototype's function")
 9}
10new Foo().instanceFunction()
11//This is an instance function

The above always uses the instance function. If instance function was not there, it would look inside the prototype and call the prototype function.

1function Foo() {}
2//
3Foo.prototype.instanceFunction = function () {
4  console.log("This is a prototype's function")
5}
6new Foo().instanceFunction()
7// This is a prototype function.

The difference b/w function defined in constructor function and added using prototype

Both ways have some pros and cons which are not difficult to understand. When methods are initialized within the constructor function they become the part of the instance which is created using new operator.

Advantage of using methods within constructor

  1. They can take advantage of closures so that local variables declared becomes private and are only available to be manipulated by instance methods making data more secured. Being part of an object they avoid naming collision.

Disadvantage of using methods within constructor

  1. They are bound to create memory issues if number of instances increases. It gets very important specially when dealing with page load timing.

Advantage of using prototype approach

  1. They share same logic and data among all instances reducing the overhead of creating a method for each individual instance providing memory optimization. For example a factory makes toys the price of all toys are same but name and color may be different. Then using the price as an instance variable is an over head and can be safely put in the prototype so that it can be shared among all users.
1function LaserGadget(name, color) {
2  this.name = name
3  this.color = color
4}
5LaserGadget.prototype.price = 100

Disadvantage of using prototype approach

  1. They can not access local variables directly and there will be a slight overhead of searching the prototype chain. In order to access private variable an instance method can be called which returns the private variable as shown below.
 1function Foo() {
 2  var private = 10
 3  this.getPrivateVaribale = function () {
 4    return private
 5  }
 6}
 7//
 8Foo.prototype.accessPrivateVariable = function () {
 9  console.log("This is a prototype's function " + this.getPrivateVaribale())
10}
11new Foo().accessPrivateVariable()
12// This is a prototype's function 10;

From above it should be clear that whether it is prototype function or simple value defined on a prototype. The first preference is given to instance members not prototype members. Thus a variable defined on both as done above using function will yield same result giving preference to instance variable rather than prototypal variable as shown below;

1function Thing(name) {
2  this.name = name
3}
4Thing.prototype.name = 'foo'
5var thing = new Thing('computer')
6console.log(thing.name) // computer
7delete thing.name // true
8console.log(thing.name) // foo

Hybrid Approach

The best way may be to use hybrid approach, it all depends upon the case and differ from one to another. If you take example of JQuery and look into the code you will find that methods are initialized within constructor while the other approach may be more suitable when the constructor object may need extending like in coffee script and

So far we have discussed creating objects with object literal, Object constructor and from user defined Constructor to create multiple instances from the prototype. There exist another way of creating object in JavaScript language known as creating with Factory function.

Constructor function can also be defined as function expression

To write the same constructor function as a function expression is also common among programmers. Both function declaration of a constructor function and function expression of a constructor function are correct with one already discussed difference of hoisting. They are also known as pseudo class

1var Animal = function (itsName) {
2  this.name = itsName
3  this.showName = function () {
4    console.log('This is ' + this.name)
5  }
6}
7
8var cat = new Animal('Timmy')
9cat.showName() //

Constructor function example from Metalsmith project

 1function Metalsmith(directory) {
 2  if (!(this instanceof Metalsmith)) return new Metalsmith(directory)
 3  assert(directory, 'You must pass a working directory path.')
 4  this.plugins = []
 5  this.ignores = []
 6  this.directory(directory)
 7  this.metadata({})
 8  this.source('src')
 9  this.destination('build')
10  this.concurrency(Infinity)
11  this.clean(true)
12  this.frontmatter(true)
13}

The constructor makes sure that if new is forgotten it calls itself and assign two properties and then carry on invoking functions. But these functions are not declared so how it is possible to do this. Well this constructor takes help from inheritance. These functions are presumably inherited. If they are not inherited an error will be thrown.

They are added in prototype as shown below.

1   Metalsmith.prototype.directory = function(dirName){
2    if (! successful) return (some error or warning)
3    // use assertion
4    this._dirName = dirName;
5    return this;
6   }

Creating objects with factory functions

Factory function is a name given to a unique way of creating objects either from other objects in prototype based programming or from a class in class based programming. Factory pattern deals with the problem of creating objects without the need to specify the exact class of the object being created providing an abstraction to constructing objects. The way they differ from constructor functions that they do not make use of a new operator because there are no constructor functions. The above Animal(itsName) constructor may be written in its simplest form as a factory function in a following way:

 1//Factory function
 2function Animal(itsName) {
 3  // A new object created and referenced by that
 4  var that = {
 5    name: itsName,
 6    isAlive: function () {
 7      return breathes === true ? 'yes' : 'no'
 8    },
 9    showName: function () {
10      // console.log(name); error
11      console.log(that.name)
12    }
13  }
14  //private members not visible outside the function
15  var breathes = true
16  // returning object
17  return that
18}
19var dear = Animal('beauty')
20dear.isAlive() //yes
21dear.breathes //error breathes is private dear has no access to it

Note: -1.No use of new operator. -2.The object that can have any name. -3.Properties are accessed either by using object name and dot (.) notation or using this.

Similarly there is very clear distinction between private and public members. Variables defined outside the objects within the factory function are visible to the objects but not to the outside world. On the other hand object properties act as public members and used by the instances outside the function. Note inside the object’s member function the property name can not be accessed by its name.

It should also be noted that there is no need to return a named object, an unnamed object can also be returned as shown.

 1function Animal(itsName) {
 2  return {
 3    name: itsName,
 4    isAlive: function () {
 5      return breathes === true ? 'yes' : 'no'
 6    },
 7    showName: function () {
 8      // console.log(name); error
 9      console.log(this.name)
10    }
11  } // un-named object return
12  //private members
13  var breathes = true
14}

Practical use of Factory Pattern

The factory pattern suggest defining an interface for creating an object where you allow the subclasses to decide which class to instantiate. This pattern handles the problem by defining a completely separate method for the creation of objects and which sub-classes are able to override so they can specify the ‘type’ of factory product that will be created. This is quite useful, in particular if the creation process involved is complex. You can often find factory methods in frameworks where the code for a library may need to create objects of particular types which may be sub-classed by scripts using the frameworks.

1function penFactory() {}
2penFactory.prototype.penClass = Pen
3penFactory.prototype.getPen = function (options) {
4  return new this.penClass(options)
5}

Anothe example of JavaScript Factory Function

 1var Person = {
 2  name: 'Person',
 3  properties: {
 4    firstName: {
 5      range: 'NonEmptyString',
 6      label: 'First name',
 7      writable: true,
 8      enumerable: true
 9    },
10    lastName: {
11      range: 'NonEmptyString',
12      label: 'Last name',
13      writable: true,
14      enumerable: true
15    }
16  },
17  methods: {
18    getFullName: function () {
19      return this.firstName + ' ' + this.lastName
20    }
21  },
22  create: function (slots) {
23    // create object
24    var obj = Object.create(this.methods, this.properties)
25    // add special property for *direct type* of object
26    Object.defineProperty(obj, 'type', {
27      value: this,
28      writable: false,
29      enumerable: true
30    })
31    // initialize object
32    Object.keys(slots).forEach(function (prop) {
33      if (prop in this.properties) obj[prop] = slots[prop]
34    })
35    return obj
36  }
37}

Notice that the JS object Person actually represents a factory-based class. An instance of such a factory-based class is created by invoking its create method: var pers1 = Person.create( {firstName:"Tom", lastName:"Smith"});

The method getFullName is invoked on the object pers1 of type Person by using the ‘dot notation’, like in the constructor-based approach:

console.log ("The full name of the person is: " + pers1.getFullName());

Notice that each property declaration for an object created with Object.create has to include the ‘descriptors’ writable: true and enumerable: true, as in lines 5 and 7 of the Person object definition above.

Advantage of Factory function over Constructor function

Creating Object with Object.create(prototype) method

When building is-a relation in JavaScript that is to create more specific object from generalized objects,the process is performed what is known as as prototyping. It is a process where one object is created using already defined object with the help of a function Object.create(prototype). A newly created object shares behaviour from not only its prototype but from the chain above, if it exist until a null is found.

This process also takes place implicitly when you create a singleton object using literal or using a Object() constructor whereby a new object is created with system provided prototype object which is already defined in, and placed as a property of the Object. This process is shown below to explain that both object are created from the same constructor internally and with the same prototype object.

1var obj1 = {}
2var obj2 = Object.create(Object.prototype)
3console.log(obj1.constructor === obj2.constructor) //true
4console.log(Object.getPrototypeOf(obj1) === Object.getPrototypeOf(obj2)) //true
5console.log(obj1.__proto__) // {}. Object.prototype

The above lines testifies that an object created with object literal is same as object created with the default prototype. The last line of code Obj1.__proto__ returns a prototype object. This internal property __proto__ is set to default prototype object when object is created.

Let’s see another example where a new object is created with another object as its prototype.

1var animal = { breathe: true } // A prototype object
2var rabbit = Object.create(animal)
3console.log(Object.getPrototypeOf(rabbit)) // { breathe:true}
4console.log(rabbit.__proto__) // {breathe: true}
5// creating another object and using __proto__ property
6var kangroo = {}
7kangroo.__proto__ = animal
8console.log(Object.getPrototypeOf(kangroo)) //{ breathe: true}

Before ECAMScript-5 Object.create() method, __proto__ property was used to point new objects’ prototype which can still be used. In above example rabbit was created from animal and animal by default have its prototype set to Object.prototype. Thus rabbit gets to share all the code from prototype chain. In order to stop inheriting the prototype chain, this property needs to point to a null object. This can be done directly or using ECMAScript-6 function. It is explained below.

1var animal = { breath: true }
2Object.setPrototypeOf(animal, null) // or animal.__proto__ = null;
3console.log(Object.getOwnPropertyNames(animal)) // [`breath`]
4console.log(Object.getPrototypeOf(animal)) // null
5var rabbit = Object.create(animal)
6console.log(rabbit.breath) // true. Inherited property

The use of property __proto__ is an old style when other methods were not available. The same result is achieved by using a static function defined on Object in ECMAScript-6, like many others Object.setPrototypeOf(obj,prototype).

Changing the prototype when working with constructor function

Not always we are dealing with a singleton object but types i.e., often with many instances of a same type. As learned before, constructor function provides a blue print for the required type to be created. Thus all item created from the constructor share the properties set in the constructor. If an object is created from the constructor function. This constructor provides the new object its identity or known as type and act like a class. Since in JavaScript there are no classes, they are regarded as pseudo classes, an achievement of duck typing. By default when a new object is created using a new operator from its constructor function, the returned object by default gets access to all members including variables and methods as well as share all services/code from the constructor function prototype, the default happens to be Object.prototype object. Let’s see the scenario explained below.

 1function Animal(name) {
 2  this.name = name
 3}
 4var rabbit = new Animal('Bunny')
 5console.log(Object.getPrototypeOf(rabbit)) // Animal{}
 6console.log(Object.getPrototypeOf(Object.getPrototypeOf(rabbit))) //{}. default
 7console.log(Object.getOwnPropertyNames(rabbit)) // [`name`]
 8// to get the inherited properties
 9var allProp = []
10for (var o = rabbit; o !== null; o = Object.getPrototypeOf(o)) {
11  for (var name of Object.getOwnPropertyNames(o)) {
12    allProp.push(name)
13  }
14}
15console.log(JSON.stringify(allProp))
16/* ["name","constructor","hasOwnProperty","constructor","toString","toLocaleString","valueOf","isPrototypeOf","propertyIsEnumerable","__defineGetter__","__lookupGetter__","__defineSetter__","__lookupSetter__","__proto__"] */
17// Note if at this stage, Animal is augmented using its prototype property by adding any function or variable. That addition will show here.

To change the default prototype Object.setDefaultPrototype() can also be used to set it to null so that it no longer inherits services from the the default prototype automatically. One might get tempted to change it into a constructor function though it will work but it will be semantically wrong

1function Animal(name) {
2  this.name = name
3  Object.setPrototypeOf(this, null)
4}
5var rabbit = new Animal('Bunny')
6console.log(Object.getPrototypeOf(rabbit)) // null

The result above shows that rabbit has no prototype or in other words no class which is not right. What needs to be achieved is that this class does not share any code from its default prototype. This is done below using a property called prototype available to function object when created. This property was used earlier to add method or properties to a default Object.prototype. Now it can be used to set the prototype of this Object.prototype object __proto__ property to null stopping to inherit any more.

1function Animal(name) {
2  this.name = name
3}
4var rabbit = new Animal('Bunny')
5console.log(Object.getPrototypeOf(rabbit)) // Animal
6// Setting default prototype to null
7Animal.prototype.__proto__ = null
8console.log(Object.getPrototypeOf(Object.getPrototypeOf(rabbit))) //null

What is shown above requires understanding of JavaScript design and prototypal inheritance.

Prototypal Inheritance

In JavaScript there is no concept of one class extending another class. Inheritance which is one of the bases of Object Oriented Programming is implemented by a Prototypal inheritance. In JavaScript every object created is a type of Object and inherits some properties implicitly from Object.prototype object to share.

A user defined object can also use its inherited property __proto__ to extend another object.

1var animal = { eats: true }
2var kangroo = { jump: true }
3// kangroo is a kind of animal
4// extending animal
5kangroo.__proto__ = animal
6console.log(kangroo.eats) //true

When an object is a prototype of another object it inherits its’ (super object) properties. If the same property is also defined in the object which is inheriting the properties ( called derived objects )then its prototype is not checked. This process is of defining a same property in subclasses is known as overriding.

1var lameKangroo = { jump: false }
2lameKangroo.__proto__ = kangroo
3console.log(lameKangroo.jump) //false

If a property is not found in the derived object its prototype is checked if it is also not found there, it is assigned undefined type.

1var fish = { swims: true }
2fish.__proto__ = animal
3console.log(fish.hasLegs) // undefined
4var result = fish.hasLegs === undefined ? 'true' : 'false' // true
5var result = fish.hasLegs ? 'true' : 'false' // false
6//console.log("result = " + result);

It is a user responsibility to override the properties in subclass otherwise they may get assigned properties which many not be true.

1//add new property to super class
2animal.hasLegs = true
3console.log(fish.hasLegs) //true(?)
4//override `haslegs` property in fish class
5fish.hasLegs = false
6console.log(fish.hasLegs) //false

To avoid the ambiguity either designed the super class intelligently making no assumptions or override which is not true in derived class. A method can be added to objects in a same way

 1//a method can be added to a class
 2animal.moves = function moves(steps) {
 3  console.log('I have walked ' + steps + ' steps')
 4}
 5kangroo.moves(2)
 6fish.moves(3)
 7//overriding moves in fish class
 8fish.moves = function moves(meter) {
 9  console.log('I have swam ' + meter + ' meters')
10}
11fish.moves(4)
12//similarly kangroo can override move method too
13kangroo.moves = function (jump) {
14  console.log('I have done ' + jump + ' jumps')
15}
16kangroo.moves(10)
 1//
 2var animal = {
 3  hasmoved: false,
 4  eats: true,
 5  moves: function (steps) {
 6    console.log('I have moved ' + steps + 'steps')
 7  }
 8}
 9var kangroo = {
10  jumps: true,
11  moves: function (jump) {
12    console.log('I have done ' + jump + ' jumps')
13    this.hasmoved = true
14  }
15}
16var fish = {
17  swims: true,
18  moves: function (swim) {
19    console.log('I have swam ' + swim + ' meters')
20    this.hasmoved = true
21  }
22}
23kangroo.__proto__ = animal
24fish.__proto__ = animal
25kangroo.moves(2)
26console.log(kangroo.hasmoved) //true
27console.log(fish.hasmoved) //false
28fish.moves(10)
29console.log(fish.hasmvoed) // now true

The above code tells us that a property of a super class in not shared among derived classes every derived class gets its own set of properties which gets updated irrespective of others. Since properties belong to individual derived object reading the property this.prop or deleting the property delete.prop only effects the object referred by this key word.

Working with prototypes

  • There is another way of working with prototypes objects that is creating an object from its prototype by using a function Object.create(<prototype>). This is regarded as a standard way of creating a prototype object. The reason being that not all JavaScript engine supports __proto__ property but all support this way of creating an object.Thus the above can be done in a following way
 1var animal = {
 2  eats: true,
 3  hasmoved: false,
 4  hasmoved: function () {}
 5}
 6kangroo = Object.create(animal)
 7console.log(kangroo.eats) //true
 8//adding properties to kangroo
 9kangroo.jumps = true
10//to find out the prototype of any object use `getPrototypeOf(object)`
11console.log(Object.getPrototypeOf(kangroo)) //returns the base object
12//checking if kangroo is akind of animal
13var result = Object.getPrototypeOf(kangroo) === animal ? true : false
14console.log(result)

Creating object with class using ES6

  • Classes in ES6 are not hoisted. Conventionally the name starts with a capital letter.
1class Point {
2  constructor(x, y) {
3    this.x = x
4    this.y = y
5  }
6}
  • Unlike function class must be defined before they are to be used.
1const p1 = new Point(10, 20) // will throw an error
2
3class Point {}
4
5var square = new Rectangle(20, 20) // ok function declartion will be hoisted
6
7function Rectangle(width, height) {}

Class Expressions

  • Another way of defining a class, it can be named or unnamed. If unnamed it can be found with its identifier name using name property.
  • Like functions it can be assigned to any identifier
 1// unnamed
 2let Rectangle = class {
 3  constructor() {}
 4}
 5console.log(Rectangle.name) // Rectangle
 6
 7let Rectangle = class Rectangle1 {
 8  constructor() {}
 9}
10console.log(Rectangle.name) // Rectangle1

ES6 class body and methods

  • Class fields / members such as methods, constructors are defined within curly brackets {}.
  • There can only be one constructor, it is to create and initialize and object created with a class constructs.
  • The key word super can be used to call the constructor of the parent class.
  • In class method can be defined without a keyword function.
  • Both static fields and method can be defined in a class, they are only to be used by the class and not to be shared with instances.
  • Classes can have both public and private properties.
  • Public properties can be used by instances but private properties can only be used within the class.
  • Public fields / properties are declared first just before the constructor.
  • Private fields / properties are declared preceded with #. They must be declared upfront and can not be declared

Sub classing

  • A child or more specialized class is created by using the word extend from its parent.
  • If a child class introduces a constructor it must call parent constructor first.
  • If a child class over rides parent class method, it can first call parent method using super.method()
 1Class Animal{
 2    constructor(name){
 3        this.name = name;
 4    }
 5    speaks(){
 6        console.log(`${this.name} does speak.`);
 7    }
 8}
 9
10Class Rabbit extends Animal {
11    constructor(name){
12        super(name); // calls parent / super class constructor
13    }
14
15    // over riding parent method
16    speak(){
17        // can call super method super.speak()
18        console.log('${this.name} does not speak.');
19    }
20}
21
22let buny = new Animal('Buny');
23buny.speak(); // buny does not speak

Mix-ins

  • Classes can not extend regular objects, to do so you must use Object.setPrototypeOf() method.
 1const Animal = {
 2    speak(){
 3        console.log("This is a normal object created with object literals");
 4    }
 5}
 6class Dog {
 7    constructor(name){
 8        this.name = name;
 9    }
10    speaks(){
11        console.log('${this.name} barks');
12    }
13}
14// Class Dog now inherits from Animal
15Object.setPrototypeOf(Dog.prototype,Animal);
16let d = new Dog('Mori');
17d.speaks(); // Mori barks
18``
19[//]: # ( End of this file)
20
21### Code used
22
23```javascript
24
25/**
26 * Autohor:Abdul Ghafoor Sayyed
27 * Date:04/11/2015
28 */
29//Creating different  objects
30var empty = {}; //an empty object created with object litrels.
31var emptyWithNew = new Object();        //same as above but used new operator though not prefered
32var point = { x : 0, y : 0};        //an object with two properties note "=" sign is not used but ":""
33var anotherPoint = {x:point.x, y:poit.y};       //value of property itself is an expression ( complex)
34var line ={p1:point,p2:point};      //
35//o1 and o2 both inherits methods from Object.prototype
36
37o1.x = 1;       //o1 object set its property name x  and give value 1.
38
39var p =  Object.create(o1);     // A static method to create another object from a prototype
40p.x = 2;        //p also set its property x , it does not change o1 property
41console.log(p.x , o1.x);

Above both ways do create an object but fails to provide a way to create same type of objects without repeating the code.

 1var Dictionary = {
 2  If: {
 3    you: {
 4      can: '',
 5      make: ''
 6    },
 7    sense: ''
 8  },
 9  of: {
10    the: {
11      sentence: {
12        it: '',
13        worked: ''
14      }
15    }
16  }
17}
18
19function Iterate(obj) {
20  for (prop in obj) {
21    if (obj.hasOwnProperty(prop) && isNaN(prop)) {
22      console.log(prop + ': ' + obj[prop])
23      Iterate(obj[prop])
24    }
25  }
26}
27Iterate(Dictionary)