Tania Rascia Web Design and Development

Skip Navigation
Object Oriented Pattern: JavaScript Constructor Functions, ES6 Classes, and PHP Classes

Object Oriented Pattern: JavaScript Constructor Functions, ES6 Classes, and PHP Classes

By Tania Rascia  /  6 responses

A comparison of class instantiation and object inheritance with JavaScript ES5 constructor functions, JavaScript ES6 classes, and PHP classes.

I wrote an article on Understanding Prototypes and Inheritance in JavaScript for DigitalOcean, in which I explained how to use constructor functions and create new objects that inherit from them. I thought it would be interesting to rewrite the exact same code as a JavaScript ES6 class and a PHP class, and get the same output. So here is a side-by-side comparison of the same pattern and output in ES5, ES6, and PHP.

Using the ES6 classes, I’ll explain what the pattern is doing.

We’ll create a class (an object blueprint) and extend the class (inheritance). I’m using the RPG character classes for the example.

// Creating a class
class Hero {}

// Extending a class
class Warrior extends Hero {}

I’ll add a constructor() function to assign two parameters to the class.

class Hero {
    // Assigning parameters with constructor
    constructor(name, level) {
        this.name = name;
        this.level = level;
    }
}

// Extending a class
class Warrior extends Hero {}

I’ll add a method as well.

class Hero {
    constructor(name, level) {
        this.name = name;
        this.level = level;
    }

    // Adding a method
    greet() {
        return `${this.name} says hello.`;
    }
}

class Warrior extends Hero {}

We’ll edit the inherited class now, adding a new parameter. We use super() to access the parameters from the parent – otherwise the inherited class would not be able to access and work with them.

class Hero { ... }

class Warrior extends Hero {
    // Adding a constructor
    constructor(name, level, weapon) {
        // Access and call function from parent
        super(name, level);

        this.weapon = weapon;
    }
}

Finally, we’ll add a method to the extended class.

class Hero { ... }

class Warrior extends Hero {
    constructor(name, level, weapon) {
        super(name, level);

        this.weapon = weapon;
    }

    // Adding a method
    attack() {
        return `${this.name} attacks with the ${this.weapon}.`;
    }
}

Now that the class and extended class blueprints are ready, we can create a new character that has acesss to the parameters and methods of the original class and the extended class.

// Initialize individual character instance
const hero1 = new Warrior('Bjorn', 1, 'axe');

console.log(hero1.attack());
console.log(hero1.greet());

The full code and output for JS constructor functions and classes, and PHP classes is below.

JavaScript ES6 Class

The class keyword was introduced with ES6. Classes are built on prototypes in JavaScript.

classes-es6.js
class Hero {
    constructor(name, level) {
        this.name = name;
        this.level = level;
    }

    greet() {
        return `${this.name} says hello.`;
    }
}

class Warrior extends Hero {
    constructor(name, level, weapon) {
        // Access and call function from parent
        super(name, level);

        this.weapon = weapon;
    }

    attack() {
        return `${this.name} attacks with the ${this.weapon}.`;
    }
}

// Initialize individual character instance
const hero1 = new Warrior('Bjorn', 1, 'axe');

console.log(hero1.attack());
console.log(hero1.greet());
Output
Bjorn attacks with the axe. Bjorn says hello.

JavaScript ES5 Constructor Function

JavaScript constructor functions were created as an attempt to bring the functionality of traditional object-oriented class design to the JavaScript language.

constructor-functions-es5.js
function Hero(name, level) {
    this.name = name;
    this.level = level;
}

function Warrior(name, level, weapon) {
    // Access and call function from parent
    Hero.call(this, name, level);

    this.weapon = weapon;
}

// Link prototypes and add prototype methods
Warrior.prototype = Object.create(Hero.prototype);

Hero.prototype.greet = function () {
    return this.name + ' says hello.';
}

Warrior.prototype.attack = function () {
    return this.name + ' attacks with the ' + this.weapon + '.';
}

// Initialize individual character instance
const hero1 = new Warrior('Bjorn', 1, 'axe');

console.log(hero1.attack());
console.log(hero1.greet());
Output
Bjorn attacks with the axe. Bjorn says hello.

PHP Class

Here is a simple example of a PHP class constructor.

class-php.php
<?php

class Hero {
    public function __construct($name, $level) {
        $this->name = $name;
        $this->level = $level;
    }
    public function greet() {
        return "{$this->name} says hello.";
    }
}

class Warrior extends Hero {
    public function __construct($name, $level, $weapon) {
        // Access and call function from parent
        parent::__construct($name, $level, $weapon);

        $this->weapon = $weapon;
    }

    public function attack() {
        return "{$this->name} attacks with the {$this->weapon}.";
    }
}

// Initialize individual character instances
$hero1 = new Warrior('Bjorn', 1, 'axe');

echo $hero1->attack();
echo $hero1->greet();
Output
Bjorn attacks with the axe. Bjorn says hello.

Of course, JavaScript classes are “syntactic sugar” (ugh) over prototypes, which means under the hood, ES6 classes are not actually running on an object-oriented inheritance model. However, popular libraries like React tend to make a lot of use of classes, so they’re good to know. The PHP example shows an actual class from a traditional object-oriented system, but with this simple example, we can get the same output either way.

Personally, I prefer syntactic salt.

Email List

Get friendly updates, infrequently.

Tania Rascia

Hiya. I'm Tania, a web developer from Chicago. Hope you enjoyed my ad-free, bullshit-free site. If you liked it, tell someone about it!

 GitHub  Twitter

Write a response

Your email address will not be published.

Discussion

  • Esteban says:

    Hi Tania,

    First of all, thanks for your amazing work providing quality content for the community 🙂

    I have not tested this but I think I spotted a typo on this line : `parent::__construct($name, $level, $weapon);`

    Shouldn’t it be `parent::__construct($name, $level);` ?

    Thanks again for your hard work ! It’s so great 🙂

    • Tania says:

      Test it out and report back!

      • Esteban says:

        Hey again !

        `parent::__construct($name, $level);` seems to be the correct way of doing it although PHP doesn’t throw an error on function overload (I looked it up). It does however when too few arguments are provided.

        I hope this is clear enough (I am not a native English speaker).

        Have a nice day 🙂

  • Liciof says:

    I have read this article and also the linked one (Understanding Prototypes and Inheritance in JavaScript); excellent, as usual!

    Thanks a lot for sharing.

  • Alex C. says:

    Hey Tania, thanks for the article; I like how you included examples for both ES5 and ES6.

    Regarding the question you put out to your readers in your newsletter, would you be willing to write some more articles on ES6, and possibly Webpack (not sure if you’ve had to use this yet).

    Thanks! 🙂

    • Tania says:

      Hi! Glad you liked it. Yes, I’m absolutely going to write more about ES6 and make a Webpack setup article. I want to do a simple side-by-side comparison of a lot of ES6 features to their ES5 counterparts, because there doesn’t seem to be a good, simple source for this.