簡體   English   中英

Static 變量 inheritance 在 Javascript (ES6)

[英]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

在 Babel 實驗模式下


上面是實驗語法。 然后我看到一篇文章說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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM