【发布时间】:2016-01-26 07:25:20
【问题描述】:
我试图弄清楚 Javascript 如何完全支持 OOP。幸运的是我可以通过 Babel 找到一些线索,并且知道它是如何向下兼容 ES5 的。
但我发现继承中的静态变量行为很奇怪。
例如,我想记住超类中的全局属性。但似乎从子类访问的静态变量实际上并不是指超类。这在经典 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
上面是实验语法。 然后我看到一篇文章说 ES6 还不支持静态属性。所以我按照他的示例重写为静态方法(getter/setter),样式,但仍然不知道......
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”指的是子类,不是超类,结果是一样的……
此外,我在 PHP 中尝试了相同的代码,然后得到了预期的结果:
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
到目前为止,我们应该说Javascript不支持静态变量继承吗?甚至在 ECMA6 中?
有什么优雅的解决方案吗?
【问题讨论】:
-
但是你的js代码和你的php不同
-
简而言之:
this.count与self->count相同,而不是self::count -
是的!我在问我们如何在JS中使用
self::count之类的东西,但不能直接通过类名访问,例如:Animal.count,这似乎违反了封装原则 -
静态类成员首先不是对象的一部分。那么为什么
Animal.count会破坏封装呢?通过self::引用静态成员基本上是自欺欺人(没有双关语)。
标签: javascript oop inheritance ecmascript-6