To update the value of an existing property, we can simply reassign a new value to it; the statement, 'objDragon.name = "Glaurung";' would update the value of "name" property from "Kilgharrah" to "Glaurung". To add a new property, we can assign something to the new property, as if it already existed and we are merely modifying it. Thus, 'objDragon.place= "Camelot";' would add a new property, "place" to "objDragon". Lastly, to delete an existing property, we can use the delete operator -- "delete objDragon.place" would delete "place" property.
Running a typeof operator for an object returns the string "object". Thus, "typeof objDragon" would return the string "object".
Next, we provide a simple example that defines an object, "objFable" with two properties: "name" and "dragon". After defining the object, this example updates, adds, and deletes its properties. This example (output is shown in comments) demonstrates that we can dynamically add a new property ("description") or delete an existing one. Lastly, trying to access a deleted property simply returns "undefined".
Here is the output when we save the above example in a file and access it using a browser:
Objects are fairly versatile in terms of what they contain; they can even contain other objects as their property values.
Let us modify the earlier objFable so that, it now includes another object (as property "characters"). Further, we also add a new property, "printFable" that is actually a method. This method prints properties of the object using a for/in loop. While iterating in the loop, this method uses typeof operator to determine the type of the property and if the typeof returns "function", then the loop skips those properties, since there is no point in printing functions. Additionally, if the typeof returns "object", then it means that this property is an object and so printFable() uses another for/in loop to print the child object.
We provide the output (as seen on a browser) when we run the above example.
name: Farmer Giles of Ham dragon: Chrysophylax characters: protagonist: Giles, the Farmer antagonist: Chrysophylax, the Dragon
However, there is one important caveat! If we modify the behavior of the object via the reference copy, then we would end up modifying the original object as well. This is because with reference, the copy is just a "link" to the original object and thus, modifying one would automatically modify the other.
Let us demonstrate this behavior using the below-provided example. We take the previous "objFable" object and then make a copy of it. When we modify the property values for the copied object, then the original object also gets modified.
The above example shows that if we do need to create an independent copy of an object, then we are better off avoiding the reference method. One safe approach is to use the first one as a Prototype for the new object and then manually copy values from the original object to the new one; we will discuss prototypes and this approach shortly in a subsequent section.
Sometimes, it is more convenient to write a program such that it invokes a chain of methods, one after another. We can achieve this multiple invocations in one statement, as long as each method returns the object after its execution is complete. This is because if the returned value is an object itself, then we can to invoke the object's method once again on the return value. This technique is popularly referred to as Method Chaining.
Let us look at a simple example to understand method-chaining in more detail. This example (provided below) defines a simple object warlock that has three methods: summonTheDragon(), rideTheDragon(), and instructTheDragon(). Each of these methods return the "this" value which refers to the object being invoked that is object warlock.
From the output (provided below), we can see that the invocation happens from left to right. The warlock object first invokes summonTheDragon() method and the summonTheDragon then returns the object warlock. Next, the chain invokes the rideTheDragon() followed by the instructTheDragon() method.
Let me summon the Dragon Let me ride the dragon Let me instruct the dragon
This section describes some of the commonly used built-in objects: Array, String, Date, Number, and Boolean.
To define these objects, we can use the "new" keyword to create an instance of an object of these types; the "new" keyword invokes the constructor method defined by the respective prototype. Thus, to create an array, all we need to do: 'var a = new Array("Kilgharrah");'. This statement would invoke the constructor method provided by Array.prototype (the prototype of all Array objects).
Similarly, we can use Boolean object to define an object that holds a boolean value (true or false). We can invoke the Boolean constructor (made available by Boolean.prototype) to create an object that stores the current date. Another type of built-in object is that of Date and we can invoke the Date constructor (made available by Date.prototype) to create an object that stores the current date.
Some of these objects like String, Number, and Boolean are essentially a wrapper objects around their primitive counterparts: string, number, and boolean. These objects provide a host of methods that allow us to process the primitive value stored in these objects. Since the primitive types are immutable and offer limited capabilities, providing a built-in wrapper object significantly enhances their usability.
We provide a trivial example that invokes constructors for some of these built-in methods and then prints their value. We will revisit both Array and String objects later in this module.
All of these prototypes come with a host of methods. If we wish to see the list of all methods published by a prototype, then we can use Object.getOwnPropertyNames() method. This method returns an array that holds all the properties published by the object. As an example, "Object.getOwnPropertyNames(Array.prototype)" would return an array holding all methods published by Array.prototype.