Javascript’s fundamental datatype is the object. An object allows you to store primitive values or other objects and retrieve those values by name. Within an object is an unordered collection of properties, each of which has a name and a value. Property names are strings. The string of a property maps to a value. The string-to-value mapping system is also known as a “hash”, “hashtable”, “dictionary” or “associative array”. In addition to maintaining its own set of properties, a Javascript object also inherits the properties of another object, known as its “prototype”. The methods of an object are typically inherited properties, and this “prototypal inheritance” is a key feature to Javascript.
Although properties in javascript objects can be added and deleted. They can be used to simulate static objects and “structs” of statically typed languages. Furthermore, javascript objects can be used to represent sets of strings. To do so, objects simply ignore the value part of the string-to-value mapping system.
The most common thing to do with objects is to create them, and to set, query, delete, test, and enumerate their properties. We will explore these fundamental operations on objects throughout this blog. Once we explore said operations and other fundamental concepts, we will jump into class linked lists (singly and doubly linked lists).
Property
A property has a name or key and a value (key-value pairs). A property name may be any string, including an empty string, but no object may have two properties with the same name. The value can be any value in Javascript, or in ECMAScript 5, it may be a getter and/or setter function. Each property has associated values known as property attributes. Below is an explanation of those property attributes:
The writable attribute specifies whether the value of the property can be set.
The enumerable attribute specifies whether the property name is returned by the for/in loop.
The configurable attribute specifies whether the property can be deleted and whether its attributes can be altered.
Having the ability to configure the attributes of your properties, as stated above, is unique to the ECMAScript 5 specification. In addition to its properties, every object has three associated object attributes:
- An object’s prototype is a reference to another object from which properties are inherited.
- An object’s class is a string that categorizes the type of an object.
- An object’s extensible flag specifies whether new properties may be added to the object (ECMAScript 5).
Three broad categories of objects
A native object is an object or class of objects defined by the ECMAScript specification. Objects such as arrays, functions, dates, and regular expressions.
A host object is an object defined by the host environment (such as the browser) within the Javascript interpreter is embedded.
A user-defined object is any object created by the execution of Javascript code.
Two types of properties
An own property is a property defined directly on an object.
An inherited property is a property defined by an object’s prototype object.
Creating Objects
With our new profound knowledge of objects and their basic fundamentals. We will take an in-depth look at creating objects and performing operations with/against objects.
In its most basic and fundamental form, we create objects as object literals with the new keyword, and in ECMAScript 5 with the Object.create() function. Let's explore both techniques.
Object Literals
An object literal is a comma-separated list of colon-separated name:value pairs, enclosed within curly braces. A property name is a Javascript identifier or a string literal. A property value is any Javascript expression; the value of the expression becomes the value of the property. As an example:
var empty = {}; // An object with no properties
var point = { x:0, y:0 }; //
Two properties var point2 = { x:point.x, y:point.y+1 } // More complex values
var book = {
“main title”: “JavaScript”, // Property names include spaces,
‘sub-title’: “The Definitive Guide”, // and hyphens, so use string literals.
“for”: “all audiences”, // For is a reserved word, so quote.
author: { // The value of this property is
firstname: “David”, // itself an object. Note that surname: “Flanagan” // these property names are unquoted.
}
};
Object literals are expressions that create and initialize a new and distinct object each time it is evaluated. The value of each property is evaluated each time the literal is evaluated. This means that a single object can create many new objects if it appears within the body of a loop in a function that is called repeatedly, and that the property values of these objects may differ from each other.
Creating Objects with new
The new operator creates and initializes a new object. The new keyword must be followed by a function invocation. A function used in this way is called a constructor and serves to initialize a newly created object. Example:
var o = new Object(); // Create an empty object: same as {}.
Prototypes
Let's take a step back and examine a very important concept about javascript objects. Specifically prototype.
All objects created by object literals have the same prototype object. We refer to this prototype object in Javascript code as Object.prototype. Objects created using the new keyword and a constrictor invocation use the value of the prototype property of the constructor function as their prototype. To clarify, an object created by new Object() inherits from Object.prototype. The same goes for an object created by the {}.
One of the things to note about objects, is a rarity with javascript, Object.prototype has no prototype: it does not inherit any properties. However, all of the built-in constructors have a prototype that inherits from Object.prototype. For example, Date.prototype inherits properties from Object.prototype. Therefore a Date object created by new Date() inherits properties from both Date.prototype and Object.prototype. This linked series of prototype objects is known as a prototype chain.
Object.create()
ECMAScript 5 defines a method, Object.create(), that creates a new object, using its first argument as the prototype of that object.Object.create() also takes an optional second argument that describes the properties of the new object.
Object.create() is a static function, not a method invoked on individual objects. To use it, simply pass the desired prototype object:
var foo = Object.create({x:1, y:2}); // foo inherits properties x and y.
You can pass null to create a new object that does not have a prototype, but if you do this, the newly created object will not inherit anything, not even the basic methods like toString():
var bar = Object.create(null); // bar inherits no props or methods
If you want to create an ordinary empty object (like the object returned by {} or new Object()), pass Object.prototype:
var baz = Object.create(Object.prototype); // baz is like {} or new Object()
Querying and Setting Properties
To obtain the value of a property, use the dot (.) or square bracket ([ ]) operators. The left-hand side should be an expression whose value is an object. If using the dot operator, the right-hand must be a simple identifier that names the property. If using square brackets, the value within the brackets must be an expression that evaluates to a string that contains the desired property name:
Given the following object:
var book = {
“main title”: “JavaScript”, // Property names include spaces,
‘sub-title’: “The Definitive Guide”, // and hyphens, so use string literals.
“for”: “all audiences”, // For is a reserved word, so quote.
author: { // The value of this property is
firstname: “David”, // itself an object. Note that surname: “Flanagan” // these property names are unquoted.
}
}
We would query its property as follows:
var author = book.author // Get the “author” property of the book.
var name = author.surname // Get the “surname” property of the author.
var title = book[“main-title”] // Get the “main title” property of the book.
Inheritance
Javascript objects have a set of “own properties”, and they also inherit a set of properties from their prototype object. To understand this we must consider property access in more detail. The example in this section uses the inherit() function in order to create object specified prototypes.
var o = {}
o.x = 1;
var p = inherit(o);
p.y = 2;
var q = inherit(p);
q.z = 3;
var s = q.toString();
q.x + q.y
Now suppose you assign to the property x of the object o. If o already has an own(non-inherited) property named x, then the assignment simply changes the value of this existing property. Otherwise, the assignment creates a new property named x on the object o. If o previously inherited the property x, that inherit property is now hidden by the newly created own property with the same name.
var unitcircle = { r:1 };
var c = inherit(unitcircle);
c.x = 1;
c.y = 1;
c.r = 2;
unitcircle.r;
Do note: The rules that specify when a property assignment succeeds and when it fails are intuitive but difficult to express concisely. An attempt to set a property p of an object o fails in these circumstances:
o has an own property p that is read-only: it is not possible to set read-only properties. o has an inherited property p that is read-only: it is not possible to hide an inherited read-only property with an own property of the same name.
o does not have an own property p; o does not inherit a property p with a setter method, and o’s extensible attribute is false. If p does not already exist on o, and if there is no setter method to call, then p must be added to o. but if o is not extensible, then no new properties can be defined on it.
* Example code used from JavaScript The Definitive Guide 6th edition. By David Flanagan and Published by O’Reilly Media.