I'm trying to figure out how does Javascript completely support OOP. Luckily I can find some clue through Babel and know how it do downward compatibility to ES5.
But I found the static variable behaviors strange in inheritance.
For example, I want to remember global properties in superclass. But it seems static variable accessed from subclass is not actually refers to superclass. Is this reasonable in classical OOP?
class Animal {
constructor(){
this.constructor.count += 1;
console.log('An animal was born');
}
static count = 0;
static sum = function(){
console.log('There are', this.count, 'animals');
}
}
class Cat extends Animal{
constructor(){
super(); // throws exception when not called
console.log(' -- the animal is a cat');
}
}
var cat1 = new Cat();
var cat2 = new Cat();
Cat.sum(); // should be 2
Animal.sum(); // should be 2, but result is 0
In the above was expermental syntax. Then I saw an article says static property is not supported in ES6 yet. So I follow his example rewriting into static method (getter/setter), style, but still got no idea.....
class Animal {
constructor(){
this.constructor.countOne();
console.log('An animal was born');
}
static countOne(){
this.count = (this.count||0)+1;
}
static sum(){
console.log('There are', this.count, 'animals');
}
}
Animal.count = 0; // Remove this, Animal.sum() will be undefined
class Cat extends Animal{
constructor(){
super();
console.log(' -- the animal is a cat');
}
}
var cat1 = new Cat();
var cat2 = new Cat();
Cat.sum(); // should be 2
Animal.sum(); // should be 2, but result is 0
"this" refers to subclass, not superclass, result is the same...
Furthermore, I try the same code in PHP, then I got expected result:
class Animal{
static $count = 0;
static function sum(){
echo "There are " . self::$count . " animals <br>";
}
public function __construct(){
self::$count++;
echo "An animal was born <br>";
}
}
class Cat extends Animal{
public function __construct(){
parent::__construct();
echo " - the animal is a cat <br>";
}
}
$cat = new Cat();
$cat = new Cat();
$cat = new Cat();
Cat::sum(); // is 3
Animal::sum(); // is 3
So far, should we say static variable inheritance is not supported by Javascript? even in ECMA6?
Is there any graceful solution?
this.countis same asself->countand notself::countself::countin JS, but not directly accessing by class name such as:Animal.countwhich seems to break encapsulation principleAnimal.countbreak encapsulation? Referring to static members viaself::is basically self-deception (no pun intended).