Objects are the basic key to understand object-oriented programming. Programming objects are just like real-world objects. Look around, you'll see many objects. Your car, mobile phone, desk, laptop, pet dog, and DVD player are all objects.
All objects have two characteristics: properties and methods.
A mobile has properties (color, screen size, height, and weight) and methods (make calls, send SMSs, receive calls, and transfer files).
A car has properties (color, height, gearbox, wheels, engine, brakes, and steering) and methods (start engine, steer, change gear, apply brake, stop, and crash).
Just like these real-world examples, the objects in OOP have the same characteristics. So, an object, in terms of programming, can have properties (variables in any programming language) and methods (functions in any programming language).Hence, we can define an object as "an entity or a thing that has some properties and methods associated with it. An object can be individually selected and manipulated".
All generic properties and methods are combined into a template called a class. A class is then used as a template to instantiate single or multiple objects. In JavaScript, there are many built-in objects, such as Maths, Dates, Regular Expressions, Arrays, and so on.
In JavaScript, we can create objects in three different ways:
This is the simplest way to create an object. An object can be both created and defined in one statement using an object literal. An object literal is a comma-separated list of name:value
(like year:1990, age:25) pairs enclosed within curly brackets.
Here is an example:
var car= { model:"2014", company:"Honda", color:"White" };
In the preceding example, we have created a car
object with four properties or attributes.
var empty = {}
On the other hand, this piece of code creates an object with no properties.
The new
keyword is used to create and initialize a new object. The
new
keyword is always followed by a function call. This function is known as a constructor, which initializes the newly created object. JavaScript contains built-in constructors for the native types.
Here is an example:
var car = new Object(); car.model = "2014"; car.company = "Honda"; car.colour = "White";
The preceding example also creates a new car
object with four properties:
varempty = new Object(); // An empty object, same as {}. vararr = new Array(); // An empty array, same as []. varcurrdate = new Date(); // Current Date. varregex = new RegExp("JavaScript"); // A pattern matching object.
The
object.create()
method was originally defined in ECMAScript 5. It is also used to create an object. The first argument passed to this method is the prototype of that object. The second argument is optional. It describes the object's properties.
Here is an example:
// obj1 inherits properties model, company and colour. varcar = Object.create({model:"2014",company:"Honda",colour:"White"}); // car inherits no properties or methods. varcar = Object.create(null);
Null
can be passed if the object does not have any prototype. However, this object will not inherit anything:
// car is same as {} or new Object(). varcar = Object.create(Object.prototype);
To write scalable code, we need to track down the recurring sections in our code and to optimize them in a way that it's easy to maintain the code. Design patterns help us in doing this.
In a book, Addison-Wesley Professional by Erich Gamma, John Vlissides, Ralph Johnson, and Richard Helm; First edition (November 10, 1994), Design Patterns are defined as:
A design pattern names, abstracts, and identifies the key aspects of a common design structure that make it useful for creating a reusable object-oriented design. The design pattern identifies the participating classes and their instances, their roles and collaborations, and the distribution of responsibilities.
Each design pattern focuses on a particular object-oriented design problem or issue. It describes when it applies, whether or not it can be applied in view of other design constraints, and the consequences and trade-offs of its use. Since we must eventually implement our designs, a design pattern also provides sample code to illustrate an implementation.
Although design patterns describe object-oriented designs, they are based on practical solutions that have been implemented in mainstream object-oriented programming languages.
Developers usually question whether there is any best design pattern to implement in their workflow.
Actually, no single design pattern is perfect for all scenarios. Each and every web application that is developed has its own needs. We have to see which pattern will add value to our application if implemented, because all design patterns serve different solutions.
So, once we have a good understanding of design patterns, it will be easier for us to integrate a pattern into our application architecture. Design patterns are classified into three categories: creational, structural, and behavioral.
Constructors are special methods used to initialize objects. They may accept arguments, which are then used to set values to member properties and methods when the object is created. Native constructors, such as arrays and objects, are present inside JavaScript as native functions. We can also create custom constructors that define properties and methods for our custom object.
In the constructor
method, we create an object using the new
keyword. In this method, we define properties and methods with the this
keyword. Properties are defined after the =
sign. When you define each property, you must place a semicolon at the end. When you use the this
method in your script, you need to first initialize the object and then use it in your code:
A constructor is considered to be the most suitable way to implement an instance. The new
keyword tells JavaScript that we would like that function to act like a constructor and to create an instance also called object
. Within a constructor, the this
keyword is used to reference the new object.
Modules can be implemented in several ways in JavaScript. We will be discussing two of them here:
As we have read earlier, object literals are a list of name:value
pairs separated by commas enclosed inside curly braces {}
. Names can be identifiers or strings followed by a colon. Make sure there is no comma after the last name:value
pair; otherwise, it may result in some unexpected errors:
varObjectLiteral = { variableKey: Value, functionKey: function() { //... } };
We do not have to instantiate object literals with the new
keyword.
Care should be taken to see that the keyword new
is not used at the start of the statement. This is because the opening curly bracket could be interpreted as the start of a code block.
We can add new members from the outside object as follows:
myModule.property = 'someValue';
Using modules can help in hiding data members (encapsulation) and managing code in an organized way.
In conventional software engineering, the module pattern provides public and private access to classes, methods, and variables. The focus of the module pattern is to reduce the use of global variables, minimizing the conflicts inside the code throughout the application.
This is the most famous and commonly used design pattern that is implemented in large JavaScript frameworks and extension libraries such as jQuery, ExtJS, YUI, and DoJo.
Here is an example of the module pattern that makes use of a shared private cache. This method enables us to create objects using shared storage that will, in return, optimize performance because the functions are only created one time in the start. The mixin uses the function reference to call them rather than creating a new instance of that function every time it needs them.
Here are a few advantages and disadvantages of the module pattern:
Advantages:
Disadvantages:
This pattern is almost identical to the module pattern. The only difference is that, in this pattern, all members are kept private until they are explicitly called, usually by an object literal returned by the closure from which it is defined.
Christian Heilmann engineered this pattern. He disliked the fact that we had to switch to object literal notation for the objects that we want to keep public. There was another drawback: we had to repeat the name of main object if we had to access public variables from one method into an other or call public methods.
In this pattern, we define all functions and variables as private and, at the end of module, return an anonymous object along with the pointers to the private functions and variables we would like to expose as public.
Here are a few advantages and disadvantages of the revealing module pattern:
Advantages:
Disadvantages:
This pattern ensures that only one instance of a class is created and provides a global access point to the object.
The singleton pattern is implemented by creating a class with a method whose object can only be created if it doesn't exist already. If the object already existed, the reference will be returned to that object.
It is recommended to delay the initialization of singletons in cases where they require some information that might not be available at the time of initialization. Hence, they are different from static classes or objects.
Here are a few advantages and disadvantages of the singleton pattern:
Advantages:
Disadvantages:
The observer pattern is such that if one object changes state all others are notified and can update automatically. Thus this pattern defines a one-to-many dependency relationship between objects.
In the observer pattern, an object (also called a subject/publisher) is connected to multiple other objects that are dependent on our subject. These depending objects are called observers/subscribers.
The subject broadcasts a notification whenever a change in state occurs. All observers receive the notification and update them accordingly.
The book, Design Patterns: Elements of Reusable Object-Oriented Software, describes the observer pattern as follows:
"One or more observers are interested in the state of a subject and register their interest with the subject by attaching themselves. When something changes in our subject that the observer may be interested in, a notify message is sent which calls the update method in each observer. When the observer is no longer interested in the subject's state, they can simply detach themselves."
Here are a few advantages and disadvantages of the observer pattern:
Advantages:
Disadvantages:
As the name suggests, a mediator is a person who assists in negotiations between two or more conflicting parties.
In terms of software engineering, mediator comes under the behavioral design pattern category. The pattern enables us to implement a single object through which different components of an application communicate.
The mediator pattern promotes loose coupling by ensuring that, instead of objects interacting with each other directly, they communicate across a central point.
Let's take a real-world example to understand it in a better way. Consider an airport traffic-control system. The control tower acts as a mediator, while all other planes are communicating with the control tower and waiting for the notifications to land or to take off. They do not contact each other but just with the control tower. The role of the control tower is very essential and central. Hence, it an important key for this system.
Similarly, the mediator is as important in this pattern.
When we call mediator's subscribe method, we pass in a callback, and the mediator queues up these callbacks for when the given event is fired and subsequently the decoupled object's callback is fired. Mediator triggers the signal for the object to fire, allowing the object to be decoupled from any others.
Here are a few advantages and disadvantages of the mediator pattern:
Advantages:
Disadvantages:
In the prototype pattern, objects are created on the template of the existing object through cloning.
This pattern focuses on creating an object that can be used as a template/blueprint for other objects through prototypal inheritance. JavaScript has native support for prototypal inheritance. Therefore, it's easy to work in this pattern.
Here are a few advantages and disadvantages of the prototype pattern:
Advantages:
Disadvantages:
In this pattern, commands are encapsulated as objects.
Command objects allow loosely coupled systems to separate objects that issue requests from the objects that process requests. These requests are known as events and the code that processes these requests is called an event handler.
In simpler words, we can say that the main purpose of the command pattern is separating the features of giving out commands from executing commands and delegating this feature to a different object. Practically, command objects bind an action to the object that will invoke the action. They always include a function such as run()
or execute()
. One of the biggest advantages of this pattern is that command objects with the same interface can be easily interchanged whenever needed.
Advantages:
Disadvantages:
It is useful while creating structures where generation and execution of requests do not depend on each other. We can say that a command instance can be instantiated by the client and run later by the invoker. The client and invoker may not know anything about each other.
This pattern is scalable as we can add new commands without changing any existing code.
A façade is a front layer that is presented to and is visible to the world. Behind it lies all the complexity and unpresentable objects.
The façade pattern is a structural pattern that enables us to hide the backend complexities under an interface. This pattern increases usability of the application modules. Internal features and methods are not exposed directly to developers, but they can interact with them through this façade. This pattern makes your application secure.
jQuery is an example of a JavaScript library that uses the façade pattern.
Whenever we use jQuery's $(this).animate()
or $(this).css()
function, we are using a façade. Similarly, $(document).ready()
implements a façade.
The core jQuery attributes should be considered intermediate abstractions. The more immediate burden to developers is the DOM API and facades are what make the jQuery library so easy to use.
The ready()
function has lots of complexities at the backend. jQuery simplifies browser inconsistency to ensure that ready()
is invoked at the appropriate time.
However, we only see a façade or a simple interface layer.
Here are a few advantages and disadvantages of the facade pattern:
Advantages:
Disadvantages:
Just like other creational design patterns, the factory pattern also focuses on object creation. However, it differs in the way that it does not require a constructor method to create objects.
The factory pattern provides an interface for object creation where we specify the type of factory object we need to create. Subclasses are allowed to decide which class will be instantiated so that they can specify which type of factory object will be created. Factory pattern is very extensible. Factory methods are used when collection of objects are being maintained. These collection of objects are different but still have many common methods and properties.
In this pattern, we do not use the new
keyword to create an object.
Let's take a real-time example that will clarify this pattern:
Suppose there is a garment factory. We need to create a type of garment. Instead of creating this object directly using the new
keyword, we will request a factory object for a new garment. We tell the factory which type of object is needed (a shirt, jeans, coat, a scarf, and so on). It instantiates that class and returns the object for our further usage.
ExtJS is a JavaScript library that uses this pattern. Methods for creating objects can be categorized and further sub classed.
Here are a few advantages and disadvantages of the factory pattern:
Advantages:
Disadvantages:
In OOP, mixins are classes that can be inherited by a subclass or a group of subclasses for functionality reuse.
Subclassing means to inherit properties for our new object from a super or base class object.
For instance, there is an apple
class that is able to extend from another class, fruit
. Here, fruit
is a superclass, while apple
is a subclass of fruit
. All objects of apple
inherit properties from fruit
. However, apple
is able to define its own methods and override those defined by fruit
.
If apple
needs to call an overridden method in fruit
, it's called method chaining.
If apple
needs to call fruit's
constructor, it's called constructor chaining.
Mixins let other objects inherit their functionality with a very minimal level of complexity. This pattern allows us to share functionalities from many mixins through multiple inheritance.
Here are a few advantages and disadvantages of the mixin pattern:
Advantages:
This pattern helps in decreasing function duplication and promotes reuse of functions. In applications where functionality is shared across the system, we can put the shared functions in mixins and focus on the rest of the distinct functionality in our system.
Disadvantages:
Keeping functionality in the object prototype may result in prototype pollution and may confuse tracking the origin of our functions. This may cause problems in large-scale applications.
Example:
// Detailed explanation of Mixin Design Pattern in JavaScript can be found here: http://addyosmani.com/resources/essentialjsdesignpatterns/book/#mixinpatternjavascript /* Car Class */ var Car = function(settings) { this.model = settings.model || 'no model provided'; this.colour = settings.colour || 'no colour provided'; }; /* Mixin Class */ var Mixin = function(){}; Mixin.prototype = { driveForward: function() { console.log('drive forward'); }, driveBackward: function() { console.log('drive backward'); } }; /* Augment existing class with a method from another class */ function augment(receivingClass, givingClass) { /* only provide certain methods */ if(arguments[2]) { var i, len = arguments.length; for (i=2; i<len; i++) { receivingClass.prototype[arguments[i]] = givingClass.prototype[arguments[i]]; } } /* provide all methods */ else { var methodName; for (methodName in givingClass.prototype) { /* check to make sure the receiving class doesn't have a method of the same name as the one currently being processed */ if (!receivingClass.prototype[methodName]) { receivingClass.prototype[methodName] = givingClass.prototype[methodName]; } } } } /* Augment the Car class to have the methods 'driveForward' and 'driveBackward' */ augment(Car, Mixin, 'driveForward', 'driveBackward'); /* Create a new Car */ var vehicle = new Car({model:'Ford Escort', colour:'blue'}); /* Test to make sure we now have access to the methods */ vehicle.driveForward(); vehicle.driveBackward();
In programming languages, getting and setting properties are used to get
and set
the values of an object. The g
etter
method is used to get values of properties and the setter
method is used to set values of properties.
There are two property accessors in JavaScript:
getter
and setter
are methods that help us access and manipulate the data within an object very easily. They can help us build shortcuts to access concealed information. The getter
and setter
methods work in such a way that they bind objects with a function so that they look like normal object properties.getter
: This method is a special kind of property accessor. When you want to access a property, the value is generated dynamically. Here is an example:Obj.getButtonColor();
setter
: This method is used to set properties. It passes a value as an argument and the returned value of the function is set to the property. Here is an example:Obj.setButtonColor(value);
Just like we can add properties to objects, JavaScript allows us to remove object properties as well.
The delete
operator is used to delete a property of an object. It deletes properties from the local version. The scope of a property can be reassigned to another variable on the same scope. In JavaScript, the delete
operator always returns a Boolean value. Using this keyword, you cannot delete objects declared with the var
keyword.
Let's assume we have an object like this:
varauthor = { "name":"talha", "age":"24" };
We wish to remove the age
property so that we can have a final object that looks like this:
{ "name":"talha" };
deleteauthor.age;
You can also use this command to achieve the same result:
delete author["age"];
One of the common tests performed by developers on an object is to check whether an object has a specific property or not. There are different ways to check whether an object has a given property.
In JavaScript, there are two methods for property testing:
hasOwnProperty
: This method is used to check whether an object has its own property or not. If the property is inherited from anywhere, then it will return false
:For example: samantha = new girls(); samantha.eyecolor = 'brown'; o.hasOwnProperty('eyecolor'); // returns true
propertyIsEnumerable
: This method returns true
, only if hasOwnProperty
returns true
and that property is enumerable.To check properties in JavaScript, we can use the in
keyword. If an object property has its own value, it will return true
.
Here is an example:
var girls = { name: 'Samantha', height: 'Tall', eyecolor: 'brown', address: null }; 'name' in girls; // true 'age' in girls; // false
In JavaScript, enumeration of an object's properties is done using the for-in
loop.
In JavaScript, enumerating properties are used in the for-in
loop as this loop accesses all properties of an object. When we want to check the list of properties of an object, then we use the for-in
loop to iterate properties. It assigns the name of the property to the loop variable.
Inherited objects are not enumerable, but properties that you add with these objects are enumerable.
Here is an example:
var student = { Name:"Ali", Age:"24", Edu:"Engineering" } Sudent.propertyIsEnumerable('Name'); // will return true since object's properties are enumerable for(var property in student) { Console.log(property); //will log all properties }
The information associated with every JavaScript property is called an attribute. Different types of property attributes are explained here.
There are two types of JavaScript properties:
There are four attributes that a property has:
There are three types of object properties in JavaScript:
Var x={ prop:555 }; console.log(x.prop); //its get method c.prop="xyz"; //its set method
Var x = { get name() { return getter; } }
Here's another example:
var x = { set name(val) { console.log(val); } }
[[Prototype]]
. The value of this property is either null or an object, which is used for implementing inheritance.It has two parts:
Serializing an object means converting an object into bytes so that it can be stored in memory persistently, or it can be sent across the network. These bytes can then be deserialized into the original object.
Serialization is used to store or preserve the internal state of an object. In serialization, an object can be transported or retrieved later. There are two methods of serialization in JavaScript:
JSON.stringify
JSON.parse
Here is an example:
Obj={a:1} A=json.stringify(obj); // creates a JSON String from an array or object B=json.parse(A); // parses a JSON Object 'A' in an object.
These methods can also retrieve and store objects, arrays
, strings
, true
and false
. Enumerable values are preserved or restored by the JSON.stringify()
method.
Object methods are functions that are stored as object properties. These methods can be performed by calling them directly following a variable for which the function is to be called and a . (dot).
Every object has methods, which are basically actions performed on it. A method is a property of an object.
The toLowerCase()
, toUpperCase()
, substr()
, trim()
, charAt()
, and indexOf()
methods are some of the examples of native (part of the core language) methods of a string object.
Here is an example using the toUpperCase()
method:
var book = "JavaScript Reference!"; var result = book.toUpperCase();
The value of the result will be:
JAVASCRIPT REFERENCE!
3.145.86.211