Mis à jour le 16/03/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.createfunction. Note that after we created our new objects, we would invoke a function we had created calledinit. There's often code like thisinitfunction that you want to run in order to "set up" your new object correctly, and most object-oriented languages even have some concept of thisinitfunction built directly into them. In Javascript, that built-ininitfunction is called a constructor function, and we can invoke it by using the special Javascript keywordnew.

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 itinit, 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 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 thePastryobject last chapter served as the prototype for all the pastries we created. All the functions, likeinitanddescribe, that we had defined on the Pastry object, were automatically available on all the pastries because we passedPastryin toObject.createwhen we created them.

Using the constructor function is slightly different, though. We can't just add properties to ourPastryconstructor 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 ourdescribefunction 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());

 

Don't forget "new" when calling constructor functions!

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 areturn 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 already happened silently when you called your constructor function without using thenew 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 thewindowobject (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 thenewkeyword when you're trying to initialize an object with a constructor function.

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