[英]Static variable inheritance in Javascript (ES6)
我想弄清楚 Javascript 是如何完全支持 OOP 的。幸運的是我可以通過 Babel 找到一些線索,並知道它是如何向下兼容 ES5 的。
但是我發現 inheritance 中的 static 變量行為很奇怪。
例如,我想記住超類中的全局屬性。 但似乎從子類訪問的 static 變量實際上並不是指超類。 這在經典 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還不支持static屬性。 所以我就按照他的例子重寫成static的方法(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
↑ ES6 小提琴
“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
到目前為止,我們應該說 static 變量 inheritance 不被 Javascript 支持嗎? 即使在 ECMA6 中?
有什么優雅的解決方案嗎?
您可以訪問靜態成員,例如:
Animal.count;
Animal.countOne();
Animal.sum();
在第二個示例中,當您創建新的cat時, this
引用了新的cat對象,而this.constructor
引用了Cat函數(即使它是從超級構造函數中調用的)。
提供閉包是提供靜態屬性的另一種方法。 通過將類定義包裝在函數中,您可以將變量僅作用於類,從而有效地創建了一個私有靜態變量。
例如
"use strict";
var log =function(d){console.log(d)}; // lazy zoo keeper
// need to define the intermediate container
// Ill call it zoo.
var zoo = (function() {
// now create the private static property
var count=0; // function scoped
class Animal {
constructor(){
count += 1; // count instances
log('An animal was born');
}
static sum(){ // create the static method of interagation
log('There are'+count+'animals');
}
}
class Cat extends Animal{
whatAreYou(){log("I am a cat ")};
}
// now return the classes you want to expose
return {
Animal:Animal,
Cat:Cat,
};
})(); // call the function to create a Zoo
// now you can make the the Animal and Cat public or you could
// keep zoo and pass it to another scope and have them private
// where you want.
var Animal = zoo.Animal;
var Cat = zoo.Cat;
// Use static function befor there are any instances of Animal or Cat
Animal.sum(); // displays 0
var a = new Animal(); // or new zoo.Animal();
var c = new Cat();
// access static function sum to display content of private and static (closure) property count;
Cat.sum(); // 2
Animal.sum(); // 2
在Animal
構造函數中,將this.constructor.count
更改為Animal.count
。
this.constructor.count
指的是Cat
class計數器Animal.count
指的是Animal
的計數器IE:
class Animal {
constructor(){
Animal.count += 1;
console.log('An animal was born');
}
要點是每個 class 都有自己的 static 變量,即不共享。 JavaScript 不支持傳統意義上的類,他們說它是它使用的 object 原型 model 的語法糖。 您可能會發現此鏈接很有用: https://github.com/getify/You-Dont-Know-JS/tree/2nd-ed/objects-classes
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.