如何将方法从 class 添加到另一个 class 的现有对象

How to add methods from a class to an existing object of another class

我有一个大 class,我将其分成两部分并分别加载到页面上以提高性能。核心部分首先同步加载,因为它包含关键功能,而扩展(非关键功能)稍后在页面中异步加载。

我只想要一个包含两个 classes 功能的对象。但是当 Extension 加载时,已经有一个 Core 对象。如何将 Extension 的功能添加到 Core 的对象上?

我正在使用基于 Gulp 的资产管道

Rollup = 将不同文件的 JS 打包成一个文件

Babel = 将 ES6 转译为 ES5

Uglify=最小化JS

这是我的目录结构:

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

我已将 gulp 构建任务设置为忽略“_classes”目录中的文件。 Rollup 解析 "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;

这是核心class

// file ab.js
class AB {

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

    getCar() {
        return this.car;
    }

    getFruit() {
        return this.fruit;
    }

}

这是分机 class

//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

现在我可以很好地在CDclass中导入ABclass,设置CDclass扩展AB 这会给我我想要的。但是对于我当前的 gulp 管道设置,这意味着 Rollup 会将 class AB 的副本与 class CD 以及 class AB 之前已经加载了。

由于 Rollup、Babel 和 Uglify,class 名称 ABCD 等不会持续存在,所以我不能假设 ABCD 让我在不先导入它的情况下进行扩展,导入它意味着它与 CD.

捆绑在一起

我在 window.oab 上的 ext.js 中应用了猴子补丁,这给了我想要的东西。

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