Mis à jour le 02/05/2018
  • 10 heures
  • Facile

Ce cours est visible gratuitement en ligne.

Ce cours est en vidéo.

Vous pouvez obtenir un certificat de réussite à l'issue de ce cours.

J'ai tout compris !

Use Constructor Functions

Connectez-vous ou inscrivez-vous gratuitement pour bénéficier de toutes les fonctionnalités de ce cours !

In the last chapter we talked about object prototypes and how to create new objects using theObject.create function. Note that after we created our new objects, we invoked a function we had created called init. There's often code like this init function that you want to run in order to "set up" your new object correctly, and most object-oriented languages even have some concept of thisinit function built directly into them. In Javascript, that built-in init function is called a constructor function, and we can invoke it by using the special Javascript keyword new.

To create an object using constructor functions, we simply write a standalone function containing theinit functionality that we want for our object. Instead of calling it init, this function will have the name of our object's "class." Here's how it would look if we rewrote some of our pastry code from last chapter, using a constructor function:

var Pastry = {
  // initialize the pastry
  init: function (type, flavor, levels, price, occasion) {
    this.type = type;
    this.flavor = flavor;
    this.levels = levels;
    this.price = price;
    this.occasion = occasion;
  },
  ...
}

will become

function Pastry(type, flavor, levels, price, occasion) {
  this.type = type;
  this.flavor = flavor;
  this.levels = levels;
  this.price = price;
  this.occasion = occasion;
}

Now, to instantiate it, instead of calling

Object.create(Pastry);

and then an init function, we'll simply do

new Pastry(type, flavor, levels, price, occasion);

What about the other function that was defined by our Pastry object, though? Remember that our pastries had a "describe" function:

var Pastry = {
  // initialize the pastry
  init: function (type, flavor, levels, price, occasion) {
    this.type = type;
    this.flavor = flavor;
    this.levels = levels;
    this.price = price;
    this.occasion = occasion;
  },

  // Describe the pastry
  describe: function () {
    var description = "The " + this.type + " is a " + this.occasion + " pastry, has a " + this.flavor + " flavor, " + this.levels + " layer(s), and costs " + this.price + ".";
    return description;
  }
};

This is where the Prototype comes in again.

Remember that the Pastry object last chapter served as the prototype for all the pastries we've created. All the functions, like init and describe, that we had defined on the Pastry object, were automatically available on all the pastries because we passed Pastry in to Object.create when we created them.

Using the constructor function is slightly different, though. We can't just add properties to our Pastryconstructor function, and expect them to be present on the instantiated instances of our class, because constructors aren't the same thing as the prototype of the objects they create.

Fortunately, constructor functions do have a special reference to the prototype of the objects they create, though, and you can attach inheritable properties to it, just as we did to the prototype in the last chapter. Now that we're using a constructor function, we'll assign our describe function to the Pastry prototype like this:

function Pastry(type, flavor, levels, price, occasion) {
  this.type = type;
  this.flavor = flavor;
  this.levels = levels;
  this.price = price;
  this.occasion = occasion;
}

Pastry.prototype.describe = function () {
  var description = "The " + this.type + " is a " + this.occasion + "pastry, has a " + this.flavor + " flavor, " + this.levels + " layer(s), and costs " + this.price + ".";
  return description;
}

In the last chapter we had two lines to create every new object:

var muffin = Object.create(Pastry);
muffin.init("muffin", "blueberry", 1, "$2", "breakfast");

var cake = Object.create(Pastry);
cake.init("cake", "vanilla", 3, "$10", "birthday");

console.log(muffin.describe());
console.log(cake.describe());

Now, using constructor functions, we can instantiate our objects on just one line and have the same result:

var muffin = new Pastry("muffin", "blueberry", 1, "$2", "breakfast");
var cake = new Pastry("cake", "vanilla", 3, "$10", "birthday");

console.log(muffin.describe());
console.log(cake.describe());

There's an important gotcha with constructor functions.

It's possible to forget to use the new keyword and instead call the Pastry function as a normal function, expecting it to return a pastry object. Notice though, that our constructor function doesn't have a return statement at all. The return value of a function that doesn't specify any return value, is "undefined," so that's what you get when you call your constructor function without using the specialnew keyword. This can lead to bugs when you or another user of your object library makes this fairly common oversight:

// gonna instantiate some sweet beignets...
var beignet = Pastry("beignet", "cream", 1, "$1.50", "anytime you want beignets");

console.log(beignet.describe());
> Uncaught TypeError: Cannot read property 'describe' of undefined

This would almost certainly cause your function to fail, if you're lucky!

A possibly worse, and harder to debug, danger here is not what happens when you callbeignet.describe(), but something that happened silently when you called your constructor function without using the new keyword.

Check the value of window.type after you run the Pastry function without the new keyword:

var beignet = Pastry("beignet", "cream", 1, "$1.50", "anytime you want beignets");
window.type
> beignet

You may not be familiar with the window object (we'll get into that more in the next chapter), but it's the root and basis for your entire webpage, and unintentionally assigning properties to it is really dangerous for your program, especially if you overwrite existing properties by accident.

We'll talk more about how this happens when we take a look at the ideas of scope and the global object in the next chapter. For now, remember that there's a danger in omitting the new keyword when you're trying to initialize an object with a constructor function.

Exemple de certificat de réussite
Exemple de certificat de réussite