Although a JavaScript object literal and a JavaScript instance object are both objects, they differ in their inherent nature and features
Object Literals
An object literal is “flat”. You create it, you add properties and methods to it, and all of those properties and methods are public. You can mutate any members of that object at any time. A JavaScript object literal does not, by nature, provide private scope. But any of the members of an object literal can certainly be a function that is capable of private scope. Object literals are useful because they allow you to create clean name-spaced code that is easy to pass around and consume.
Example # 1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
var data = { fname: "foo", addOne: function(num){ return num + 1} } console.log(data.fname) console.log(data.addOne(4)) data.fname = "bar"; console.log(data.fname) data.lname = "baz"; console.log(data.lname) data.say = function(){ return "this is the say function" }; console.log( data.say() ); |
In example # 1, we have defined a JavaScript object literal and assigned it to the variable “data”. This object has two members: the property “fname” and the method “addOne”. At run time, we can mutate this object very easily and add new properties (e.g. “lname”) and methods (i.e. “say”). The upside is that this object is totally exposed and we can access or mutate any of its members any time we like, with no problem. (Remember that if an object member is a function, then that function does provide its own private scope.) The downside of this object is that it does not inherently have a private scope. It also doesn’t have the kind of initialization that is provided by a constructor upon creation.
The output for example # 1 is:
Instance Objects
An instance object is what is returned when instantiating a JavaScript constructor function, using the JavaScript “new” keyword. When you say “var bar = new Foo()”, “bar” becomes an “instance” of the function “Foo()”. Any expressions within Foo() are executed, any local variables in Foo() are copied and provided in “bar”, and the value of “this” inside of “bar”, refers to “bar”. The function “Foo” is never changed in any way; it simply acts as a “blueprint” for “bar”, and “bar” is an “instance” of “Foo”. Any local variables inside of “bar” are completely private and can only be muted by privileged members of that object.
Example # 2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
var Foo = function(){ var _color= "blue"; console.log("welcome to your new instance object"); this.getColor = function(){ return _color; } this.setColor = function(newColor){ _color = newColor; } } var bar = new Foo(); // "welcome to your new instance object" console.log(bar._color); // undefined console.log(bar.getColor()); // "blue" bar.setColor("red") console.log(bar.getColor()); // "red" |
In example # 2, we have created a constructor function. A JavaScript constructor function is a function that is not meant to be executed directly. For example, we never plan to do the following: “Foo()”. Instead, a constructor is meant to be instantiated. This means that you create an “instance” of that function using the JavaScript “new” keyword. We have created an instance of Foo() by saying “var bar = new Foo()”. So, now we have a variable named “bar” that is an exact copy of Foo().
What makes “bar” differ from our JavaScript Object Literal that we defined in Example # 1, is that when our instance object (“bar”) is created, any execution code in the constructor (i.e. “Foo()” ) runs. In addition, any private variables defined in the constructor remain private in the instance object (i.e. “_color”).
What makes this scenario a little more special than that of the object literal is that we can have privileged methods. These are methods that are made public by the use of the “this” prefix, but they have access to the instance object’s private members (i.e. “_color”). So, when we run this code, the constructor function code runs (“welcome to your new instance object”). We attempt to output the value of “_color”, but “undefined” is returned, because “_color” is private and cannot be accessed outside of “bar”. We then use the privileged method “getColor()” to get the value of _color the correct way, and “blue” is returned. We then change the value of “_color” using the privileged memer “setColor()”, and return its value using “getColor()” again (“red”).
Summary
Both Object Literals and Instance Objects have their place and purpose in JavaScript. The power of Object Literals is in their lightweight syntax, ease of use, and the facility with which they allow you to create name-spaced code. Instance Objects are powerful because they are derived from a function, they provide private scope when they are created, and expressions can be executed on instantiation.
Helpful links for JavaScript Objects
http://www.w3schools.com/js/js_objects.asp
http://www.javascriptkit.com/javatutors/oopjs.shtml
[…] For an in-depth discussion of the difference between an object literal and an instance object, see the article: “What is the difference between an Object Literal and an Instance Object in JavaScript? | Kevin Ch…. […]
[…] JavaScript. Which method you chose depends on the type of Object you need to create. For example, there is a difference between an Object Literal and and instance object in JavaScript. Also, while arrays are instances of the Array() constructor, they are still considered […]
[…] In Example # 1, we have created a variable named “salesperson”. As a result, this variable becomes a constructor function. (If you are not familiar with the concept of JavaScript constructor functions, you might want to review this article: What is the difference between an Object Literal and an Instance Object in JavaScript ? | Kevin Chis… […]