Jeg skrev en artikel om Understanding Prototypes and Inheritance in JavaScript for DigitalOcean, hvor jeg forklarede, hvordan man bruger konstruktørfunktioner og skaber nye objekter, der arver fra dem. Jeg tænkte, at det ville være interessant at omskrive nøjagtig den samme kode som en JavaScript ES6-klasse og en PHP-klasse og få det samme output. Så her er en side-by-side sammenligning af det samme mønster og output i ES5, ES6 og PHP.
Ved hjælp af ES6-klasserne vil jeg forklare, hvad mønsteret gør.
Vi opretter en klasse (en objektplan) og udvider klassen (arv). Jeg bruger RPG-karakterklasserne til eksemplet.
// Creating a class
class Hero {}
// Extending a class
class Warrior extends Hero {}
Jeg tilføjer en constructor()
funktion til at tildele to parametre til klassen.
class Hero {
// Assigning parameters with constructor
constructor(name, level) {
this.name = name
this.level = level
}
}
// Extending a class
class Warrior extends Hero {}
Jeg tilføjer også en metode.
class Hero {
constructor(name, level) {
this.name = name
this.level = level
}
// Adding a method
greet() {
return `${this.name} says hello.`
}
}
class Warrior extends Hero {}
Vi vil redigere den nedarvede klasse nu og tilføje en ny parameter. Vi bruger super()
for at få adgang til parametrene fra forælderen - ellers ville den nedarvede klasse ikke kunne få adgang til og arbejde med dem.
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;
}
}
Til sidst tilføjer vi en metode til den udvidede klasse.
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}.`
}
}
Nu hvor klasse- og udvidede klasseplaner er klar, kan vi oprette et nyt tegn, der har adgang til parametrene og metoderne for den oprindelige klasse og den udvidede klasse.
// Initialize individual character instance
const hero1 = new Warrior('Bjorn', 1, 'axe')
console.log(hero1.attack())
console.log(hero1.greet())
Den fulde kode og output for JS-konstruktørfunktioner og -klasser og PHP-klasser er nedenfor.
JavaScript ES6-klasse
class
søgeord blev introduceret med ES6. Klasser er bygget på prototyper i JavaScript.
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-konstruktørfunktion
JavaScript-konstruktørfunktioner blev skabt som et forsøg på at bringe funktionaliteten af traditionelt objektorienteret klassedesign til JavaScript-sproget.
constructor-functions-es5.jsfunction 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-klasse
Her er et simpelt eksempel på en PHP-klassekonstruktør.
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.
Selvfølgelig er JavaScript-klasser "syntaktisk sukker" (ugh) over prototyper, hvilket betyder, at under hætten kører ES6-klasser faktisk ikke på en objektorienteret arvemodel. Populære biblioteker som React har dog en tendens til at gøre meget brug af klasser, så de er gode at kende. PHP-eksemplet viser en faktisk klasse fra et traditionelt objektorienteret system, men med dette simple eksempel kan vi få det samme output på begge måder.
Personligt foretrækker jeg syntaktisk salt.