So far in this book, you've heard me mention objects quite often but I've never explained what they really are. To put it simply, an object is a collection of values and methods (which are, remember, functions associated with objects). It is perfectly permissible to have an object that is all values or all methods.
I mentioned something back in back in The Document Object Model that is very important to remember. To quote it completely, Always remember that a node must actually exist before you do anything with it.
Nodes are a type of object, and what applies to them applies to all objects.
There are two ways to create an object: Either directly (which has its own shorthand method) or through a template.
Directly creating an object is actually quite easy. First, you create a variable (object), and say that it is a new object (You've done this for arrays).
var object = new Object();Then we decide what properties it's supposed to have. Properties, of course, follow the object name with a period between the object name and property name (). So, let's set the properties object.propertyNum1, Num2, Num3, and String:
var object = new Object();Num1 = 4;Num2 = 5;Num3 = 6;String = "Something Else";Now where have we seen THAT syntax before? Oh, yes, we used the data property of a text node.
So when we want to use these values, say to write to various elements, we can use their values like any other variable:
var dds = document.getElementsByTagName("dd");firstChild.data = object.String;firstChild.data = object.Num1;firstChild.data = object.Num2;firstChild.data = object.Num3;And the results are below:
Now, you might be thinking But object doesn't HAVE those properties.
Actually, when you say, Property A of Object B has Value C
, you're also saying Object B has Property A
.
I'll show you, working with nodes.
var dd1 = document.getElementByID("dd_1");var dd2 = document.getElementByID("dd_2");var js = document.getElementByID("JS");data = js.extra;extra = "Extra Text";data = js.extra;Basically, in the last three lines, I set the text of the elements dd_1
and dd_2
(both dd elements, by the way) to the property extra of js, which is assigned a reference to a paragraph element node). Element nodes do not normally have the property extra, so for dd_1
, (which is set to display that property's value before the property itself is set) it's non-existent, as shown by the word undefined
. However, once set, that particular element node has the property extra, and so dd_2
has something to display:
Like arrays, there is a shorthand method of creating objects. Instead of using []
, however, you use {}
. Also, the syntax is slightly different, because you're not dealing with just values but the properties as well. So below is our object, as we created it earlier:
var object = new Object();String = "Something Else";Num1 = 4;Num2 = 5;Num3 = 6;To use the shorthand method, you have to have a comma-separated list of properties and values. The property comes first, then a colon, then the value:
Well, where have we seen that syntax before? Oh, yes: CSS! This works on much the same principle.
In any case, the above code rewritten in shorthand would be:
var object = {String:"Something Else",Num1:4,Num2:5,Num3:6Watch out that you don't use semicolons in there, or things will get messy. Just like in arrays.
A template is a means to create multiple objects that are identical in properties, but not necessarily in values. These separate objects are known as instances, to create them is to instantiate the object. (In direct creation, the object is instantiated when you use or when you use shorthand creation.)var object = new Object()
The template itself is a function. These functions, however, do not return a value in the same way. Below, I've created a template with four variables (Num1, Num2, Num3 and String) called Template.
I know, how very imaginative.
A really important keyword in templates is this, and refers to this instance of the object.
I'll show you what I mean. Below is a template of an object:
function Template(N1, N2, N3, String){this.String = String;this.Num1 = N1;this.Num2 = N2;this.Num3 = N3;Note that the properties of this differ from the names of the variables. That is fine; but when you refer to the properties of an object created by Template, you would use Num1, Num2, and Num3 instead of N1, N2, and N3, since the previous group are specifically stated to be the actual property names.
We create a new instance of this object by calling the template and assigning its value to object below, and declaring it to be a new instance of the object Template. This is exactly like creating a new object (see above) or new array (as shown in previous chapters).
var object = new Template(4, 5, 6, "Something else");When used in such a manner, this means this instance of Num1 is equal to 4, this instance of Num2 is equal to 5, this instance of Num3 is equal to 5, and this instance of String is equal to Something else
.
The advantage to using a template is that we can create as many instances of Template as we need. For example, I created a webpage that used a template to create a new object for every row of a table. Since that table was used to create a seven-month schedule, that template was instantiated more than two hundred times.
Below, I create an array containing two separate instances of it (though we could use two separate variables entirely).
var objects = new Array(new Template(4, 5, 6, "Something else"),new Template(8, 10, 12, "Different Text")Before I demonstrate more, I should tell you about a trick that's possible: when one refers to the property of an object, you usually have the object, a period, then the property. An example would be to refer to the length of the array objects:
lengthBut it is permissible to act as if the object were an array, and use the property name as a string in place of an index number. The code also refers to the property length:
"length"]This is important, because strings can be manipulated, as you will see in the code that assigns text to elements:
function Text(r, c){return r.getElementsByTagName("td")[c].firstChild;}var trs = document.getElementsByTagName("tr");for(var l = 1; l < trs.length; l++){Text(trs[l], 1).data = objects[l - 1].Stringfor(var l2 = 1; l2 <= 3; l2++){Text(trs[l], (l2 + 1)).data = objects[l - 1]["Num" + l2]As you know, three properties share the letters Num
. Concatenating the strings with the properties' respective numbers allows me to assign their text to text nodes via a loop. Below, each row represents a different instance of the object Template, and you can see their different values:
A method is a function associated with an object. Making a function a method is actually quite easy: treat the function name like a variable. First, we create the function Get_El, saying that its purpose is to get an element. It can get an element by ID or by tag name, and if the second value is undefined, then treat the first like an ID:
function Get_El(name, num){var el;if(num == undefined){document.getElementById(name);else {document.getElementsByTagName(name)[num];return el;Just a note here: I didn't try to use num as a boolean in and of itself (Example: ) since, in that condition, a value of 0 would also prove if(!num)not
right along with falseundefined, but in the case of node lists, 0
refers to the first element in that list. Therefore, only an undefined value will cause it to treat the first value as an ID instead of an element name.
The next two samples deal with direct creation; the third deals with a template:
var object = new Object();Num1 = 4;Num2 = 5;Num3 = 6;String = "Something Else"Get_El = Get_El;var object = {Num1:4,Num2:5,Num3:6,String:"Something Else"Get_El:Get_Elfunction Template(N1, N2, N3, String){this.Num1 = N1;this.Num2 = N2;this.Num3 = N3;this.String = String;this.Get_El = Get_El;var object = new Template();Note that, in the template (which I left otherwise unaltered), I did not add a function variable to the function Template to deal with the new property
Get_El. Since Get_El is a method, not a property, I don't need to; I pass values to it when I use Get_El through the object. In the following example, I show accessing Get_El through an object created via template, but I also display one minor redundancy:
headfunction Get_El(name, num){var el;if(num == undefined){document.getElementById(name);else {document.getElementsByTagName(name)[num];return el;function Template(N1, N2, N3, String){this.Num1 = N1;this.Num2 = N2;this.Num3 = N3;this.String = String;this.Get_El = Get_El;var object = new Template();bodyvar object = new Template();var fee_fie = object.Get_El("write_to");var foe_fum = Get_El("get_from");firstChild.data = foe_fum.firstChild.data;The variable foe_fum accesses Get_El directly, rather than through object. Since Get_El is a global function, this works:
If you want Get_El to be exclusive to Template so you don't have functions tripping over each other, nesting functions comes in handy.
function Template(N1, N2, N3, String){this.Num1 = N1;this.Num2 = N2;this.Num3 = N3;this.String = String;this.Get_El = Get_El;function Get_El(name, num){var el;if(num == undefined){document.getElementById(name);else {document.getElementsByTagName(name)[num];return el;var object = new Template();A trick that can save some code is assigning the function itself to the property, rather than just the function's name:
function Template(N1, N2, N3, String){this.Num1 = N1;this.Num2 = N2;this.Num3 = N3;this.String = String;this.Get_El = function (name, num){var el;if(num == undefined){document.getElementById(name);else {document.getElementsByTagName(name)[num];return el;var object = new Template();Now, if I try to access Get_El directly, I get an error saying it's undefined. It does not exist outside of the template or objects created thereby. As I said earlier, it's a good way to keep functions from tripping over each other.
It is quite possible (and common) to nest an object within an object. It's like nesting arrays or functions. To demonstrate this, I will place the number properties in their own object called Numbers:
var object = new Object();Numbers = new Object();Numbers.Num1 = 4;Numbers.Num2 = 5;Numbers.Num3 = 6;String = "Something Else"Get_El = function (name, num){var el;if(num == undefined){document.getElementById(name);else {document.getElementsByTagName(name)[num];return el;var object = {Numbers:{Num1:4,Num2:5,Num3:6String:"Something Else"Get_El:function (name, num){var el;if(num == undefined){document.getElementById(name);else {document.getElementsByTagName(name)[num];return el;function Template(N1, N2, N3, String){this.Numbers = new Numbers(N1, N2, N3);this.String = String;this.Get_El = function (name, num){var el;if(num == undefined){document.getElementById(name);else {document.getElementsByTagName(name)[num];return el;function Numbers(Num1, Num2, Num3){this.Num1 = Num1;this.Num2 = Num2;this.Num3 = Num3;var object = new Template();Note that, when I nest a template (in this case Numbers) inside another template (Template), I call it like any other template.
Combining the above methods, of course, is perfectly acceptable:
var object = new Object();Numbers = {Num1:4,Num2:5,Num3:6var object = {Numbers:new Numbers(4, 5, 6);function Numbers(Num1, Num2, Num3){this.Num1 = Num1;this.Num2 = Num2;this.Num3 = Num3;function Template(N1, N2, N3, String){var Numbers = new Object();Num1 = N1;Num2 = N2;Num3 = N3;this.Numbers = Numbers;this.String = String;this.Get_El = Get_El;function Get_El(name, num){var el;if(num == undefined){document.getElementById(name);else {document.getElementsByTagName(name)[num];return el;var object = new Template();Mostly we've been getting specific data from objects, but there are more ways of getting what you need than what I've showed you thus far.
For example, earlier in the chapter I mentioned that the property name can be used like an array's index, if the property's name is passed as a string. This might not seem like much, but there is an interesting application: you can specify the property you want using a variable.
"Num1";This will come in handy when you want to get all the properties and values in an object, including the ones you don't know about.
You can use a loop to go through the properties of an object, one by one. However, you should know that the only loop that does so is the for-in loop; other loops need to know what properties the object has beforehand.
But do note that for-in loops have a challenge of their own. Take a look at the following code example:
var object = new Template(4, 5, 6, "Something else");for(property in object){The variable property, because it refers to the names of the properties of object, will always hold a string, never a number. Therefore, the following code will not work:
var object = new Template(4, 5, 6, "Something else");for(property in object){document.getElementsByTagName("tr")[property].getElementsByTagName("td")[0].firstChild.data = object[property];A node list must use a numerical index, not a textual one. Therefore, a separate counter must be created to work with those. Adding in the counter and another line of code to display the actual value of property, we get:
var object = new Template(4, 5, 6, "Something else");var count = 1;for(property in object){document.getElementsByTagName("tr")[count].getElementsByTagName("td")[0].firstChild.data = property;document.getElementsByTagName("tr")[count].getElementsByTagName("td")[1].firstChild.data = object[property];This yields the following: