使用ES6模块,如何导出和导入单个类方法?

23

假设我有一个简单的类在fileA.js中,如下所示:

class foo {
    constructor(x) {
        this.name = x
    }

    fooMethod(x) {
        return x + 'hello';
    }
}

我想在fileB.js中使用以下方式导入并使用fooMethod

import { fooMethod } from './fileA';

class bar() {
    ...
    barMethod(x) {
        return fooMethod(x);
    }
}

我该如何在fileA中编写export以实现这一点?


1
export { foo.prototype.fooMethod as fooMethod }可能可行。 - gcampbell
@IlyaNovojilov 不,这将导出类,而不是裸方法。 - Lux
但正如Lux所指出的那样,最好找到一种替代的结构方式(原型方法应该在某个东西上调用,而不是自己调用)。 - gcampbell
@Lux 我有多个类型为 bar 的模块/类,它们共享相同的功能。为了避免在每个类中重复自己,我想将相同部分移动到不同的父类(如 foo)中。由于我只能使用一个其他类来 extend 类,因此我的选择受限,我正在寻找其他实现方式。共享的方法在模板中经常使用,因此它们需要尽可能短。import {fooMethod) from ... 将直接访问 fooMethod 而无需调用 className.fooMethod。希望这有意义。 - Rotareti
@le0m,我已经编辑了我的答案。请查看。 - Lux
显示剩余3条评论
5个回答

17

你需要在原型上导出它。但请记住,如果这样做,你将无法在类/对象上下文中调用该函数:

export foo.prototype. fooMethod

然而,我建议您不要这样做。


好的,由于您的评论,您想要一种好的方法来为两个不扩展相同基类的类提供共同功能。一个简单的方法是从两个类中导入一个实用函数:

foo.js

export function foo() {
  return this.name;
}

a.js

import {foo} from 'foo';
export class A extends BaseA {
  foo() {
    foo.apply(this, arguments);
  }
}

b.js

import {foo} from 'foo';
export class B extends BaseB {
  foo() {
    foo.apply(this, arguments);
  }
}

这个模式对于单个功能来说很好,但如果您想应用更复杂的功能,则有限制。实现这一点的好方法是混合模式:

foo.js

export default superClass => class extends superClass {
  foo() {
    return this.name;
  }
};

a.js

import foo from 'foo';
export class A extends foo(BaseA) {
  ..
}

b.js

import foo from 'foo';
export class B extends foo(BaseB) {
  ..
}

这将使您的混合创建一个新的匿名类,它位于您的类'A'/'B'和'BaseA'/'BaseB'之间,为共同的函数foo提供支持。


那么,想要在fileB中使用类foo的上下文获取fooMethod的唯一方法是导入整个foo类并从中调用fooMethod - Rotareti
你需要一个对象来拥有上下文,而不是一个类。因此,你需要初始化一个对象。也许创建一个单例? - Lux
这个混合模式看起来非常有趣!我能用这种方式扩展一个类,使其具有多个类似于foo的类吗:class A extends fooOne(fooTwo(Base)) - Rotareti

9

您需要将其导出为单独的变量/常量,如下所示:

class Foo {
  fooMethod() {};
}

export const fooMethod = Foo.prototype.fooMethod;

请查看Babel/repl。编辑:在评论中发现您不需要实例方法(不使用this)。只需定义和使用常规函数即可。
export function fooMethod(x) {
    return x + 1;
}

9

您可以通过实例化类将其转换为对象,然后通过从新实例化的对象解构每个方法来导出类方法。请查看以下代码示例。

像这样解构并导出对象方法:

class foo {
  doSomething() {
    // some stuffs
  }

  doAnotherThing() {
    // do something else
  }

}

export const { doSomething, doAnotherThing } = new foo()

然后在您想要导入方法的文件中执行以下操作:

import { doSomething, doAnotherThing } from '../class/file/directory'

doSomething() // calls the method

我希望这可以帮到您。

3

这是我通常解决helper类中函数exports的方法。使用helper类的单例是首选,这就是为什么它在这里能够正常工作的原因。不确定您是否接受创建单例,但它可以很好地工作。

class foo {
  constructor(x) {
    this.name = x
  }

  internalFooMethod(x) {
    return x + 'hello';
  }
}

const singleton = new foo();
export default singleton;

export function fooMethod(x) {
  return singleton.internalFooMethod
}

然后在 fileB.js 中导入并调用它:

import { fooMethod } from './fileA';

class bar() {
    barMethod(x) {
        return fooMethod(x);
    }
}

当然,我们可以导入默认类 foo 和导出的函数:

import FooSingleton, { fooMethod } from './fileA';

-3

最好不要导出方法。遵循这个。

文件A

export class foo {
    constructor(x) {
        this.name = x
    }

    fooMethod(x) {
        return x + 'hello';
    }
}

app.component.ts

import { Component } from '@angular/core';
import { foo } from './fileA';

@Component({
  moduleId: module.id,
  selector: 'app-root',
  templateUrl: 'app.component.html',
  styleUrls: ['app.component.css']
})
export class AppComponent {
  title = 'app works!';
  constructor(private fooClass: foo){
      this.fooClass.fooMethod('');
  }
}

6
问题中没有提到OP是否使用TS或Angular,因此你的示例有很多无关信息。此外,你也没有解释为什么这样做更好,并忽略了fooMethod可以是静态的这个事实。 - ssube

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接