H2 - P2019

Développement web

Cours 12 - 2016-01-04

Javascript

Programmation orientée objet

Qu'est-ce que c'est ?

Appelée POO ou OOP

Méthode de programmation consistant à séparer les différents composants d'une logique en objets

Un objet possède des propriétés (ou attributs) et des méthodes (ou fonctions)

Utilisé en Java, C#, Objective C, PHP, Ruby, AS3, Javascript, ...

Une moto peut être considérée comme un objet en programmation.

Ses propriétés sont par exemple : couleur, vitesse, immatriculation, etc.

Ses méthodes sont par exemple : démarrer, accélerer, freiner, etc.

Un exemple javascript : Math

Ses propriétés : Math.PI, Math.E, etc.

Ses méthodes : Math.cos(), Math.sin(), Math.round(), etc.


Math.PI;    // Propriété
Math.cos(); // Méthode
                    

À quoi ça sert ?

  • Indépendance des éléments
  • Plus facile à entretenir
  • Plus lisible
  • Plus logique
  • Plus pro

Objet statique (classique)


var bike = {
    color      : 'black',
    speed      : 0,
    accelerate : function()
    {
        this.speed += 1;
    }
};
                    

this à l'intérieur d'une méthode fait référence à l'objet bike
On appelle ça le context

Cette méthode fonctionne bien, mais pose problème quand on a plusieurs objets du même type


// Première moto
var bike_1 = {
    color      : 'black',
    speed      : 0,
    accelerate : function()
    {
        this.speed += 1;
    }
};

// Deuxième moto
var bike_2 = {
    color      : 'red',
    speed      : 0,
    accelerate : function()
    {
        this.speed += 1;
    }
};

// Troisième moto
var bike_3 = {
    color      : 'red',
    speed      : 0,
    accelerate : function()
    {
        this.speed += 1;
    }
};
                    

Objet avec constructeur


// Class Bike
var Bike = function(color)
{
    // Propriétés
    this.color = color;
    this.speed = 0;

    // Méthodes publiques
    this.accelerate = function()
    {
        this.speed += 1;
    };
};

// Initialisation
var bike_1 = new Bike('black'),
    bike_2 = new Bike('red'),
    bike_2 = new Bike('blue');
                    

Un constructeur (on peut parler de Class) se créé à partir d'une fonction

L'initialisation se fait avec new

Un seul constructeur permet d'instancier plusieurs objets

Cette méthode fonctionne bien, mais pose problème si on souhaite créer une nouvelle classe héritant de notre constructeur

Objet avec constructeur et prototypage


// Class Bike
var Bike = function(color)
{
    this.color = color;
};

// Prototype
Bike.prototype.color      = 'black';
Bike.prototype.speed      = 0;
Bike.prototype.accelerate = function()
{
    this.speed += 1;
};

// Initialisation
var bike_1 = new Bike('black'),
    bike_2 = new Bike('red'),
    bike_2 = new Bike('blue');
                    

Chaque objet possède un prototype

Les propriétés et méthodes du prototype sont utilisées si elles n'existent pas dans l'instance

Cet objet fonctionne exactement comme le précédent sauf que nous allons pouvoir utiliser son protype pour faire de l'héritage

Objet avec héritage


// Class Bike
var Bike = function(color)
{
    // Propriétés
    this.color = color;
};

Bike.prototype = {
    color      : 'black',
    speed      : 0,
    accelerate : function()
    {
        this.speed += 1;
    }
};

// Class Bandit (héritée de Bike)
var Bandit = function(){};
Bandit.prototype = Object.create(Bike.prototype);
Bandit.prototype.brand = 'Suzuki';

// Initialisation
var bike_1 = new Bike('red'),
    bike_2 = new Bandit('blue');

                    

Nous avons créé une classe Bandit qui hérite de la classe Bike

Pour commencer, nous copions le prototype de Bike dans le prototype de Bandit avec Object.create()

La méthode instanceof permet de savoir si un objet hérite d'une classe


console.log(bike_1 instanceof Bike)
console.log(bike_1 instanceof Bandit)
console.log(bike_2 instanceof Bike)
console.log(bike_2 instanceof Bandit)
                    

Coder orienté objet est primordiale, même pour du web

Les éléments qui composent un site peuvent être encapsulés dans des objets

Exemple : Header, Sidebar, Carousel, Page

Les différents objets peuvent ensuite être séparés dans des fichiers et classés dans des dossiers

Alternatives au prototypage

Simple JavaScript Inheritance
(par John Resig, le papa de jQuery)


var Person = Class.extend({
    init: function(isDancing){
        this.dancing = isDancing;
    },
    dance: function(){
        return this.dancing;
    }
});
 
var Ninja = Person.extend({
    init: function(){
        this._super( false );
    },
    dance: function(){
        // Call the inherited version of dance()
        return this._super();
    },
    swingSword: function(){
        return true;
    }
});
 
var p = new Person(true);
p.dance(); // => true
 
var n = new Ninja();
n.dance();      // => false
n.swingSword(); // => true
                    

features

  • Héritage avec extends
  • this._super() pour appeler la méthode de la classe parente
  • Méthode init() appelée à l'instanciation

Burno.js


// Create a class wrapping the all application
B.Components.My_App = B.Core.Abstract.extend(
{
    construct : function()
    {
        // Instantiate a sidebar and header
        this.sidebar = new B.Components.My_Sidebar( { color : 'blue' } );
        this.header  = new B.Components.My_Header();
    }
} );

// Create a class for the sidebar
B.Components.My_Sidebar = B.Core.Abstract.extend(
{
    // Default options
    options :
    {
        colors : 'red'
    },

    construct : function( options )
    {
        this._super( options );

        this.main = document.querySelector( 'aside' );

        console.log( 'Init Sidebar' );
    }
} );

// Create a class for the header
B.Components.My_Header = B.Core.Abstract.extend(
{
    construct : function()
    {
        this.main = document.querySelector( 'header' );

        console.log( 'Init Header' );
    }
} );
                    

features

  • Basé sur le système de classe de John Resign
    • Héritage avec extends
    • this._super() pour appeler la méthode de la classe parente
    • Méthode construct() appelée à l'instanciation
  • Deep property merging
  • Singleton/Static
  • Options par défaut
  • Classes de base
    • Abstract
    • Event_Emitter
    • Breakpoints
    • Colors
    • Css
    • Detector
    • GA tags
    • Keyboard
    • ...

ES6 Classes


class Cat { 
    constructor(name) {
        this.name = name;
    }

    speak() {
        console.log(this.name + ' makes a noise.');
    }
}

class Lion extends Cat {
    speak() {
        super.speak();
        console.log(this.name + ' roars.');
    }
}