6  Objects

So far, we discussed five of JavaScript’s six data types. These are string, number, Boolean, undefined, and null. These are called primitive data types. Anything that is not a primitive data type is of the object data type. In the previous chapter, you learned about functions, which are of the object data type. In this chapter, you will learn how to program using object literals, which are also of the object data type.

JavaScript Data Types

The JavaScript data types are:

  • String

  • Number

  • Boolean

  • Undefined

  • Null

  • Object

The object data type includes functions, arrays, and object literals. Arrays and functions have already been explored, so here is a general definition of object literals: Object literals are a collection of comma-separated key-value pairs that are contained within curly braces.

Note: Developers in the JavaScript world commonly refer to object literals as objects. However, object literals and the object data type are two different things. One way to understand the difference is to recognize that the object data type is a category that contains object literals, functions, and arrays.

In the following code, an object named obj is created and the values within curly braces are assigned to it.

var obj = {
  key1: "value1",
  key2: "value2"
};

A key is similar to a variable, and a value is similar to the data assigned to a variable. The key and value of an object is called a property for nonfunctions assigned to a key, or a method for functions assigned to a key.

var obj = {
  key: "value", //___This is a property
  doSomething: function(){ //___This is a method
  }
};

Conceptually, object literals are used to model real-world elements in your code. So, for example, the following object is used to model a music album.

//_________________This is an object that contains album data
var album = {
  name:"Thriller Funk",
  artist:"James Jackson",
  format:"wave",
  sampleRate:44100
}

To access data from an object, you can use dot notation, which looks like this:

album.name; // Thriller Funk
album.artist; // James Jackson
album.format; // wave
album.sampleRate; // 44100

Alternatively, you can use bracket notation to access values in an object.

album["sampleRate"]; // 44100

If you use a bracket notation, you must type the key in the form of a string.

album["sampleRate"]; //__The key is a string

You can use methods to modify or retrieve data from an object. Here is an example of an object that contains a method that returns the name and artist information of an object named song.

var song = {
  name: "Funky Shuffle",
  artist: "James Jackson",
  format: "wave",
  sampleRate: 44100,
  //_____________________________BEGIN Method
    nameAndArtist: function() {
      return "Name: " + song.name + " | " + "Artist: " + song.artist
    }
  //_____________________________END Method
}

You can invoke methods with dot notation and trailing parentheses.

//__________________________________BEGIN method invocation
song.nameAndArtist(); // Name: Funky Shuffle| Artist: James Jackson
//__________________________________END method invocation

Images  Looping through Objects

To loop through the keys and values of an object, you use a for in loop. You code a for in loop like this:

var song = {
  name: "Funky Shuffle",
  artist: "James Jackson",
  format: "wave",
  sampleRate: 44100
}
//______________________BEGIN for in loop
for (var prop in song) {
  console.log(prop + ":"); //__Outputs each key
  console.log(song[prop]); //__Outputs each value
}
//______________________END for in loop

The structure of a for in loop consists of the for keyword followed by a variable that represents the value of each property. In the previous example, this variable was named prop. The variable name is followed by the in keyword and the name of the object you want to loop through.

Often you will want to modify the properties of an object you are looping through while not modifying any of its methods. One way you can do this is by using a conditional statement and the typeof operator to act only on property values that are not functions. This usage is shown in the following code:

var song = {
  name: "Funky Shuffle",
  artist: "James Jackson",
  format: "wave",
  sampleRate: 44100,
  nameAndArtist: function() {
    return "Name: " + song.name + " | " + "Artist: " + song.artist;
  }
};
for (var prop in song) {
  if (typeof song[prop] !== "function") {
    console.log(song[prop]); //___Omits methods
  }
}

Images  When to Use Objects Rather Than Arrays

You have probably noticed that objects and arrays are similar because they allow you to organize collections of data. If you are curious about when to use an array rather than an object, the rule of thumb is that if the order of the data matters, you should always use an array. The reason for this is that there is nothing in the JavaScript specification that guarantees the order in which key-value pairs of an object are returned in a loop.

Images  How to Check If an Object Has Access to a Particular Property or Method

If you want to check whether a property or method is available to an object, you can use the in operator.

var song = {
  name: "Funky Shuffle",
  artist: "James Jackson",
  getArtist: function() {
    return song.artist;
  }
};
console.log("artist" in song); //true
console.log("getArtist" in song); //true

Images  Cloning Objects

If you want to create an object that has access to another object’s properties and methods, while being extensible, you can use the Object.create() function. The following example shows an object being cloned using this method.

var effects = {
  reverbs: {
    hall: "Hall reverb being used",
    plate: "Plate reverb being used",
    smallRoom: "Small room reverb being used"
  },
  guitar: {
    flange: "Flange being used",
    wahWah: "Wah wah being used"
  }
};
var updatedEffects = Object.create(effects);
console.log(updatedEffects.reverbs); //returns reverb object
console.log(updatedEffects.guitar); // returns guitar object

You can then extend the newly created object with properties and methods.

updatedEffects.filters = {
  lowPass: "Lowpass filter being used",
  highPass: "Highpass filter being used"
};
console.log(updatedEffects.filters); // returns filter object
console.log(effects.filters); // undefined

Images  Prototypal Inheritance

It is important to understand that Object.create() does not literally copy the properties and methods to a new object but provides a reference to the properties and methods contained in the parent object(s). This hierarchy of references between objects is called prototypal inheritance. The following code shows this by cloning multiple objects and including comments of the hierarchy of property accessibility.

var synth = {
  name: "Moog",
  polyphony: 32
};

var synthWithFilters = Object.create(synth); // clone synth
// synthWithFilters now has access to name and polyphony properties
synthWithFilters.filters = ["lowpass", "highpass", "bandpass"]; 
  // add property
/*The original synth object does not have access to the filters 
  property.*/
var synthWithFiltersAndEffects = Object.create(synthWithFilters); 
  // clone synthWithFilters
synthWithFiltersAndEffects.effects = ["reverb", "flange", 
  "chorus"]; // add property
/*Neither the synth object nor the synthWithFilters object have 
  access to the effects property*/

Images  The "this" Keyword

JavaScript contains a keyword called this that is used in methods to refer to an object. In the following code, the method named nameAndArtist references its containing object directly by using its name, which is song.

var song = {
  name: "Funky Shuffle",
  artist: "James Jackson",
  format: "wave",
  sampleRate: 44100,
  //_____________________________BEGIN Method
  nameAndArtist: function() {
    return "Name: " + song.name + " | " + "Artist:" + song.artist;
  }
  //_____________________________END Method
};

The reference to song can be replaced with the this keyword, and the result is the same.

nameAndArtist: function() {
  return "Name: " + this.name + " | " + "Artist: this.artist";
};

Images  The bind Function

The usefulness of the this keyword becomes apparent when you realize that any function or method can be applied to any object. The easiest way to demonstrate this is by using the built-in JavaScript method called bind. The bind method points a function’s this value to the object specified in the first argument (the bound object). You can then invoke the function on the bound object. In the following code, bind points the getName function’s this value to an object named album.

var song = {
  name: "Funky Shuffle",
  artist: "James Jackson",
  format: "wave",
  sampleRate: 44100
};

function getName() {
  return this.name;
}
var getNameOfSong = getName.bind(song); /*assign bound function to 
  a variable*/
//_______Then invoke it!
console.log(getNameOfSong()); // Funky Shuffle

If you want to specify arguments in a function created with bind, you can do this in one of two ways. The first is to specify the arguments in the newly created function. In the following example, a function named descriptor is invoked on an object named blastSound. An argument is then passed to the describeBlastSound function.

var blastSound = {
  name: "Blast"
};

function descriptor(message) {
  return this.name + ": " + message;
}

var describeBlastSound = descriptor.bind(blastSound);
console.log(describeBlastSound("This is an explosive sound")); 
  //Blast: This is an explosive sound

Alternatively, you can specify the arguments in the statement where you bind the function to the object. You do this by first specifying the object to bind to, then specifying arguments you want to use and separating them with commas, as in the following example:

var describeBlastSound = descriptor.bind(blastSound, "This is an 
  explosive sound");
console.log(describeBlastSound()); /*Blast: This is an explosive 
  sound*/

As you can see, even when a function has not been written as a method on a particular object, you can still apply the function to that object. This also means that you can use a method of one object and apply it to a completely different object. The following code uses a method named getNameAndArtist of an object named song and applies it to an object named Album.

var album = {
  name: "Funky Shuffle",
  artist: "James Jackson",
  format: "wave",
  sampleRate: 44100
};
var song = {
  name: "Analogue Heaven",
  artist: "The Keep It Reels",
  getNameAndArtist: function() {

    return "Name: " + this.name + " | Artist: " + this.artist;
  }
};
var getNameOfAlbum = song.getNameAndArtist.bind(album);
console.log(getNameOfAlbum()); /*Name: Funky Shuffle | Artist: 
  James Jackson*/

If a function is invoked outside the context of an object, its this value points to one of two values, depending on whether strict mode is used or not. If strict mode is used, its this value is undefined. If strict mode is not used, its this value points to an invisible object called the global object, which contains all the built-in properties and methods of the web browser. You can view the value of this by using console.log(this) in the global scope without strict mode.

Images

Images  Summary

In this chapter, you learned how to program with objects. In the next chapter, you will learn the basics of the Web Audio API node graph and working with oscillators.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.191.185.40