Как добавить методы из класса в существующий объект другого класса - PullRequest
0 голосов
/ 20 апреля 2019

У меня был один большой класс, который я разделил на два и загрузил их отдельно на страницу, чтобы улучшить производительность. Основная часть загружается сначала синхронно, поскольку она содержит критические функции, а расширение (некритические функции) загружается позже на странице асинхронно.

Я хочу только один объект, который содержит функциональность обоих классов. Но к моменту загрузки Extension уже есть объект Core. Как добавить функциональность из Extension в объект Core?

Я использую конвейер активов на основе Gulp с

Скопление = для объединения JS из разных файлов в один файл

Бабель = перевести ES6 в ES5

Uglify =, чтобы минимизировать JS

Вот моя структура каталогов:

js
|_ _classes
|   |_ ab.js
|   |_ cd.js
|_ core.js
|_ ext.js

Я поставил задачу сборки gulp игнорировать файлы в каталоге "_classes". Сводный пакет анализирует операторы import для связывания кода.

Это то, что у меня есть в core.js

//core.js
import AB from './_classes/ab.js';

window.oab = new AB();

и это ext.js

//ext.js
import CD from './_classes/cd.js';

//let o_cd = new CD();

window.oab.prototype = CD;

Это базовый класс

// file ab.js
class AB {

    constructor() {
        this.car = 'McLaren';
        this.fruit = 'Mango';
    }

    getCar() {
        return this.car;
    }

    getFruit() {
        return this.fruit;
    }

}

и это класс расширения

//file cd.js
class CD {

    constructor() {
        this.plane = 'Gulfstream';
    }

    getPlane() {
        return this.plane;
    }

}

Я пытаюсь заставить это работать:

console.log( window.oab.getCar() );  // prints McLaren
console.log( window.oab.getFruit() );  // prints Mango
console.log( window.oab.getPlane() );  // prints Gulfstream

Теперь я могу очень хорошо импортировать класс AB в класс CD, установить CD class для расширения AB, и это даст мне то, что я хочу. Но с моей текущей настройкой gulp pipe это означало бы, что Rollup объединит копию класса AB с классом CD, а класс AB уже загружен ранее.

Из-за Rollup, Babel & Uglify имена классов AB & CD и т. Д. Не сохраняются, поэтому я не могу допустить, чтобы AB был доступен в CD для меня, чтобы расширить его без предварительного импорта и импорта это будет означать, что он связан с CD.

1 Ответ

0 голосов
/ 21 апреля 2019

Я применил патч обезьяны в ext.js на window.oab, и это дает мне то, что я ищу.

import CD from './_classes/cd.js';

( function() {

    let i;
    let ocd = new CD();
    let ocd_methods = Object.getOwnPropertyNames( ocd.__proto__ ).filter( p => {
        return ( 'function' === typeof ocd.__proto__[ p ] );
    });

    Object.assign( window.oab, ocd );   // this assigns only properties of ocd into window.oab and not the methods

    for ( i in ocd_methods ) {

        let method = ocd_methods[ i ];

        if ( '__proto__' === method || 'constructor' === method ) {
            continue;
        }

        window.oab.__proto__[ method ] = ocd[ method ];

    }

} () );

А теперь это работает

console.log( window.oab.getCar() );  // prints McLaren
console.log( window.oab.getFruit() );  // prints Mango
console.log( window.oab.getPlane() );  // prints Gulfstream
...