Objects Part 1

==================================================================

On this page:

  1. From arrays to objects.
  2. Elements, properties, methods, and members.
  3. Hashes and associative arrays.
  4. Accessing an object's properties.
  5. Calling an object's methods.
  6. Altering properties/methods.
  7. Using the this value..
  8. Constructor functions.
  9. The global object.
  10. The constructor property.

==================================================================

1. From arrays to objects

An array is just a list of values. Each value has an index (a numeric key) that starts from zero and increments by one for each value. Consider the following example:

> var myarr = ['red', 'blue', 'yellow', 'purple']; 
> myarr; 
["red", "blue", "yellow", "purple"]. 
> myarr[0]; 
"red" 
> myarr[3]; 
"purple" 
Example 1

An object is similar to an array, but the difference is that you define the keys yourself. You're not limited to using only numeric indexes, and you can use friendlier keys such as first_name, age, and so on. Let's take a look at a simple object and examine its parts:

var hero = { 
breed: 'Turtle', 
occupation: 'Ninja' 
}; 
Example 2

You can see that:

  • The name of the variable that refers to the object is hero
  • Instead of [ and ], which you use to define an array, you use { and } for objects
  • You separate the elements (called properties) contained in the object with commas
  • The key/value pairs are divided by colons, as in key:value

The keys (names of the properties) can optionally be placed in quotation marks. For example, these keys are all the same:

var hero = {occupation: 1}; 
var hero = {"occupation": 1}; 
var hero = {'occupation': 1}; 

Later in this Part1, you'll see other ways to define objects and arrays, in addition to [] and {}. However, first, let's introduce this bit of terminology:

Defining an array with [] is called array literal notation,

Defining an object using curly braces {} is called object literal notation.

It's recommended that you don't quote the names of the properties (it's less typing), but there are cases when you must use quotes. Some of the cases are stated here:

  • If the property name is one of the reserved words in JavaScript.
  • If it contains spaces or special characters (anything other than letters, numbers, and the _ and $ characters).
  • If it starts with a number.

2. Elements, properties, methods, and members

When talking about arrays, you say that they contain elements. When talking about objects, you say that they contain properties. There isn't any significant difference in JavaScript; it's just the terminology that people are used to, probably from other programming languages.

A property of an object can point to a function, because functions are just data. Properties that point to functions are also called methods. In the following example, talk is a method:

var cat = { 
name: 'Misja', 
talk: function () { 
alert('Miauw, 'Miauw!'); 
} 
}; 

3. Hashes and associative arrays

In some programming languages, there is a distinction between:

  1. A regular array, also called an indexed or enumerated array (the keys are numbers)
  2. An associative array, also called a hash or a dictionary (the keys are strings)

JavaScript uses arrays to represent indexed arrays and objects to represent associative arrays. If you want a hash in JavaScript, you use an object.

4. Accessing an object's properties

There are two ways to access the property of an object:

  1. Using the square bracket notation, for example, ball['radius']
  2. Using the dot notation, for example, ball.color

The dot notation is easier to read and write, but it cannot always be used. The same rules apply for quoting property names. If the name of the property is not a valid variable name, you cannot use the dot notation.

Let's take a ball object:

var ball = { 
radius: 40, 
color: '#ff0000' 
}; 

Consider the following example for accessing a non-existing property returns undefined:

 >  var ball = { 
	radius: 40, 
	color: '#ff0000' 
	}; 
	'Ball speed is ' + ball.speed; 
	"Ball speed is undefined"

Objects can contain any data, including other objects:

var ball = { 
	radius: 40, 
	color: '#ff0000',
	velocity:{
	vx:10,
	vy:20
	} 
};

To get to the vx property of the object contained in the velocity property of the ball object, you can use the following lines of code:

> ball.velocity.vx
  10

An eample using the square brackets notation:

> ball['velocity']['vy']  
  20

It works even if you mix both:

> ball.velocity['vx']
  10

5. Calling an object's methods

Calling (invoking) a method is the same as calling any other function - you just add parentheses after the method name, which effectively says Execute!:

>	var hero = { 
	breed: 'Turtle', 
	occupation: 'Ninja', 
	say: function () { 
	return 'I am ' + hero.occupation; 
	} 
	}; 
>   hero.say(); 
	"I am Ninja" 

As you can use the array-like square brackets to access a property, it means you can also use brackets to access and invoke methods:

>	 hero.say('a', 'b', 'c');

6. Altering properties/methods

JavaScript allows you to alter the properties and methods of existing objects at any time. This includes adding new properties or deleting them. You can start with a blank object and add properties later. Let's see how you can go about doing this.

An object without properties is shown as follows:

> 	var hero = {};

Note

A "blank" object

In this section, you started with a "blank" object, var hero = {}. Blank is in quotes because this object is not really empty and useless. Although at this stage it has no properties of its own, it has already inherited some.

You'll learn more about own versus inherited properties later. So, an object in ES3 is never really blank or empty. In ES5 though, there is a way to create a completely blank object that doesn't inherit anything, but let's not get ahead too much.

6.1 Adding two properties and a method:

> 	hero.breed = 'turtle'; 
> 	hero.name = 'Leonardo'; 
> 	hero.sayName = function () { 
	  return hero.name; 
	  }; 
> 	hero.sayName();
	  "Leonardo" 

6.2 Calling a method:

> 	hero.sayName();
	  "Rafaelo" 
	  

6.3 Deleting a property:

> 	delete hero.name;
      true 

6.4 If you call the method again, it will no longer find the deleted name property:

> 	hero.sayName();
	  "Undefined" 
	  

Note

Malleable objects

You can always change any object at any time, such as adding and removing properties and changing their values. However, there are exceptions to this rule. A few properties of some built-in objects are not changeable (for example, Math.PI, as you'll see later). Also, ES5 allows you to prevent changes to objects. You'll learn more about it in Appendix C, Built-in Objects.

7. Using the this value

In the previous example, the sayName() method used hero.name to access the name property of the hero object. When you're inside a method though, there is another way to access the object the method belongs to. This method is using the special value this:

>   var hero = { 
	name: 'Rafaelo', 
	sayName: function () { 
	return this.name; 
	} 
	}; 
>   hero.sayName(); 
	"Rafaelo" 

So, when you say this, you're actually saying-this object or the current object.

8. Constructor functions

There is another way to create objects-using constructor functions. Let's look at an example:

function Rectangle() { 
      this.length = 100; 
    } 

In order to create an object using this function, you can use the new operator as follows:

>   var rectangle1 = new Rectangle(); 
>   rectangle1.lenght; 
	100 

A benefit of using constructor functions is that they accept parameters, which can be used when creating new objects. Let's modify the constructor to accept three parameters and assign it to the name, width and height properties:

function Shape(name,width,height) { 
  this.name = name; 
  this.width = width; 
  this.height= height;
  this.whatAreYou = function () { 
  return "I am a " + 
  this.name +
  " and " + 
  this.width + 
  " px long and" + 
  this.height  + 
  " px high";  
  } 
} 
  

Now, you can create different objects using the same constructor:

> var shape1 = new Shape('Square',100,100); 
> var shape2 = new Shape('Rectangle',200,100); 
> shape1.whatAreYou();
"I am a Square and 100 px long and 100 px high"
> shape2.whatAreYou();
"I am a Rectangle and 200 px long and 100 px high"

Note

By convention, you should capitalize the first letter of your constructor functions so that you have a visual clue that they are not intended to be called as regular functions.

If you call a function that is designed to be a constructor but you omit the new operator, it is not an error. However, it doesn't give you the expected result:

> var shape1 = Shape('Square',100,100); 
> type of shape1'
"undefined" 

What happened here? There is no operator, so a new object was not created. The function was called like any other function, so the variable shape1 contains the value that the function returns. The function does not return anything so it actually returns undefined, which gets assigned to the variable shape1.

In this case, what does this refer to? It refers to the global object.

9. The global object

You have already learned a bit about global variables (and how you should avoid them). You also know that JavaScript programs run inside a host environment (the browser, for example). Now that you know about objects, it's time for the whole truth, the host environment provides a global object, and all global variables are accessible as properties of the global object.

If your host environment is the web browser, the global object is called window. (This is not the case in for example Node.js where the global object is global). Another way to access the global object (and this is also true in most other environments) is to use this keyword outside a constructor function, for example in the global program code outside any function.

As an illustration, you can declare a global variable outside any function as follows:

> var a = 1; 

Then, you can access this global variable in various ways:

  • As a variable a
  • As a property of the global object, for example, window['a'] or window.a
  • As a property of the global object referred to as this:
> var a = 1; 
> window.a; 
  1 
> this.a; 
  1 

Let's go back to the case where you define a constructor function and call it without the new operator. In such cases, this refers to the global object and all the properties set to this become properties of window.

Declaring a constructor function and calling it without new returns "undefined":

> function Hero(name) { 
  this.name = name; 
  } 
> var h = Hero('Leonardo'); 
> typeof h; 
  "undefined" 
> typeof h.name; 
  TypeError: Cannot read property 'name' of undefined 

As you had this keyword inside the function Hero, a global variable (a property of the global object) called name was created:

> name; 
	"Leonardo" 
> window.name; 
	"Leonardo" 

If you call the same constructor function using new, then a new object is returned, and this refers to it:

> var h2 = new Hero('Michelangelo');      
> typeof h2;      
  "object"      
> h2.name;      
  "Michelangelo" 

The built-in global functions you have seen in Chapter 3, Functions, can also be invoked as methods of the window object. So, the following two calls have the same result:

Built-in global functions can also be invoked as methods of the window object. So, the following two calls have the same result:

> parseInt('101 dalmatians');      
  101      
> window.parseInt('101 dalmatians')     
  101 
 

10. The constructor property

When an object is created, a special property is assigned to it behind the scenes-the property. It contains a reference to the constructor function used to create this object.

Continuing from a previous example:

> function Shape(name,width,height) { 
	  this.name = name; 
	  this.width = width; 
	  this.height= height;
	  this.whatAreYou = function () { 
	  return "I am a " + 
	  this.name +
	  " and " + 
	  this.width + 
	  " px long and" + 
	  this.height  + 
	  " px high";  
	  } 
  } 
> var shape1 = new Shape('Rectangle',200,100); 
> shape1.constructor; 

	ƒ   Shape(name,width,height) { 
		this.name = name; 
		this.width = width; 
		this.height= height;
		this.whatAreYou = function () { 
		return "I am a " + 
		this.name +
		" and " + 
		this.width + 
		" …
	

As the constructor property contains a reference to a function, you might as well call this function to produce a new object. The following code is like saying, "I don't care how object shape1was created, but I want another one just like it":

> var shape2 = new shape1.constructor('Rectangle',300,100);      
> shape2.name;      
  "Rectangle" 
  

If an object was created using the object literal notation, its constructor is the built-in Object() constructor function (there is more about this later in this chapter):

> var o = {};      
> o.constructor;      
  function Object() { [native code] }      
> typeof o.constructor;      
  "function" 

 

Leave a comment