2015-05-25 12 views
5

Chcę używać EcmaScript 6 (przez Browserify i Babelify) w nowym projekcie, ale zależy to od bibliotek stron trzecich napisanych w ES5. Problem polega na tworzeniu podklas w moim projekcie, które rozciągają się od tych w bibliotekach.Rozszerzanie klas EcmaScript 5 w kodzie ES6

Np:

// Library written in ES5 
function Creature(type) { 
    this.type = type; 
} 

// my code in ES6 

class Fish extends Creature { 
    constructor(name) { 
    super("fish"); 
    this.name = name; 
    } 
} 

To prawie działa oprócz tego Creature() Konstruktor nie jest uruchamiany. I opracowali obejście/siekać który konstruuje obiekt klasy nadrzędnej pierwszy, a następnie dodaje do niej rzeczy:

class Fish extends Creature { 
    constructor(name) { 
    super("throw away"); //have to have this or it wont compile 
    let obj = new Creature("fish"); 
    obj.name = name; 
    return obj; 
    } 
} 

Takie podejście wydaje się działać tak długo, jak oryginalna klasa nie posiada funkcji „konstruktora”.

Moje pytanie brzmi: czy to najlepszy sposób na ich rozszerzenie przy korzystaniu z klas ES6 (oprócz pytania autora biblioteki o migrację)? Czy jest jeszcze lepszy sposób? Chciałbym nadal używać składni klasy {} w moim projekcie.

+1

Babel opiera się na klasach ES5, odpowiednio ustawiając "Creature.prototype.constructor = Creature", może nie robisz tego właściwie? Jeśli klasa nadrzędna jest bezwzględną podstawą, powinno to nastąpić automatycznie, ale jeśli klasa nadrzędna ma swojego rodzica, możliwe jest, że ma zły ".constructor". – loganfsmyth

Odpowiedz

2

Twoje rozwiązanie działa poprawnie przy użyciu babel. Twój kod zostanie skompilowany do następującego kodu ES5.

// Library written in ES5 
"use strict"; 

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; } 

function Creature(type) { 
    this.type = type; 
} 

// my code in ES6 

var Fish = (function (_Creature) { 
    function Fish(name) { 
    _classCallCheck(this, Fish); 

    _Creature.call(this, "fish"); 
    this.name = name; 
    } 

    _inherits(Fish, _Creature); 

    return Fish; 
})(Creature); 

Jak widać z powyższego kodu, konstruktor klasy Creature nazywa się poprawnie. Linia _Creature.call(this, "fish");.

Babel link

I dodaje się następujące kodu w celu wykazania, że ​​ryby jest wystąpienie Creature jak wystąpienie Fish.

var fish = new Fish("test"); 

console.log(fish.type); 
console.log(fish.name); 

console.log(fish instanceof Creature); 
console.log(fish instanceof Fish); 

wyjściowa:

fish 
test 
true 
true 
0

konstruktorzy ES5 i klasy ES6 mogą żyć bezproblemowo w łańcuchu dziedziczenia. Jeśli przeniesiesz swój kod, przed uruchomieniem, na ES5 za pomocą narzędzi takich jak Babel, zobaczysz, że wszystko to przekłada się na dziedziczenie oparte na prototypach. Proszę spojrzeć na ten przykład: here, który ma zarówno klasy, jak i funkcje konstruktora na trzech poziomach łańcucha dziedziczenia. Mam nadzieję że to pomoże.