2016-01-26 4 views
1

Я пытаюсь выяснить, как Javascript полностью поддерживает ООП. К счастью, я могу найти какую-то подсказку через Babel и узнать, как она совместима с ES5.Статическое наследование переменных в Javascript (ES6)

Но я обнаружил, что статические переменные поведения странны в наследовании.

Например, я хочу запомнить глобальные свойства в суперклассе. Но похоже, что статическая переменная, доступная из подкласса, на самом деле не относится к суперклассу. Является ли это разумным в классическом ООП?

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 Babel Experimental Mode


В приведенном выше был expermental синтаксис. Затем я увидел статью, в которой статическое свойство еще не поддерживается в ES6. Поэтому я следую его примеру переписывания в статический метод (геттер/сеттер), стиль, но до сих пор не получил никакого представления .....

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 Fiddle

«это» относится к подклассу, не суперкласса, результат тот же ...


Кроме того, я пытаюсь тот же код в 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?

Есть ли изящное решение?

+0

но ваш код в JS отличается от вашего PHP – Grundy

+0

в двух словах: 'this.count' такое же как' self-> count' и не 'самостоятельно :: count' – Grundy

+0

https: //devbank.wordpress.com/tag/static-variable-in-javascript/ может объяснить это – Gavriel

ответ

3

Вы можете получить доступ к статическим членам, как:

Animal.count; 
Animal.countOne(); 
Animal.sum(); 

В Вашем 2 Например, когда вы создаете новую кошку, this относится к новому объекту кошки и this.constructor относятся к функции Cat (даже если он вызывается из супер конструктора) ,

2

Существует альтернативный способ обеспечения статических свойств, и это происходит через закрытие. Объединив определения класса внутри функции, вы можете использовать переменные области видимости только для своего класса, эффективно создавая приватную статическую переменную.

Например

"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 
Смежные вопросы