ES6 - 使用 import 语句在类上声明原型方法

IT技术 javascript class import prototype ecmascript-6
2021-03-07 00:00:06

我正在使用 ES6 类。我希望能够做到这一点:

function Car(color) {
  this.color = color;
};

Car.prototype.getColor = require('./getColor');

其中 get color 是一个导出函数。即我希望能够从外部文件导入一个函数,并将其设置为 ES6 类上的原型方法。这是我正在谈论的那种语法:

class Car {
  constructor(color) {
    this.color = color;
  }

  getColor() {} // I want to import this function from './getColor', as above
}

这是可行的吗?

3个回答

你仍然可以在的原型上附加一个方法毕竟,类只是“功能对象”上的语法糖,这是使用函数构造对象的旧方法。

由于您想使用 ES6,我将使用 ES6 导入。

最小的努力,使用原型:

import getColor from 'path/to/module';

class Car {
    ...
}

Car.prototype.getColor = getColor;

如您所见,如果您愿意,您仍然使用原型属性来附加方法。


在类的方法中调用module:

或者,如果您不想使用原型属性,您始终可以让您的方法从module返回函数:

import getColor from 'path/to/module';

class Car {
    getColor () {
        return getColor.call(this);
    }
}

使用吸气剂

您也可能有点棘手,并使用“getter”以不同的方式实现这一点。

import getColor from 'path/to/module';

class Car {
    get getColor () { return getColor.bind(this) }
}

然后你可以简单地通过调用来使用它, myInstanceOfCar.getColor()

或者在更语义化的 getter 用法中:

class Car {
    get color () { return getColor.call(this) }
}

// ...

const color = myInstanceOfCar.color;

请记住,getter/setter 不能与您在构造函数中设置的属性同名。当您尝试使用 setter 设置相同的属性时,您最终会以无限递归超过最大调用堆栈。例子:set foo (value) { this.foo = value }


ES2016 类属性

如果您使用 Babel 进行转译(并且正在使用实验性提案),并且想要使用一些ES2016,您可以使用以下语法(但请记住,这将方法直接应用于对象,而不是将其设置为原型):

import getColor from 'path/to/module';

class Car {
    getColor = getColor;
}

带有类属性的可选绑定

如果您使用速记语法来设置属性,则不必绑定该方法(设置是作为属性更改“this”所指的内容,本质上是自动绑定它的),但是您当然可以,如果您选择(就像你想绑定其他东西一样):

getColor = getColor.bind(this);
对于在添加到原型时遇到绑定问题的任何人,这些必须是常规function声明。这意味着您不能使用导入的箭头函数。
2021-05-04 00:00:06
不,您不需要绑定函数。它仍然是设置 的方法调用this
2021-05-05 00:00:06
@GoogleMac 正因为如此,我个人认为应该为回调保留箭头,其中词法绑定实际上是有意义的。独立function声明应该在其他任何地方使用(但这只是我个人的偏好)
2021-05-08 00:00:06

是的。class语法仅仅是(非常复杂)的构造函数的语法糖。所以Car仍然是一个带有prototype属性的函数,你可以做完全相同的事情:

import getColor from './getColor';
// ...
Car.prototype.getColor = getColor;

但是,这使得方法可枚举,而不是从类语法创建的方法。所以你可能想Object.defineProperty改用。

@SheedySheedySheedy 如果您想要 ES6 导入,请参阅我的回答。但是,导入会被提升,因此您必须在最顶部声明​​它们。
2021-04-22 00:00:06
感谢您的回答。我明白我可以做到这一点。我可能没有从我希望在 ES6 中维护导入的新语法以及 ES6 类声明原型方法的方式(如上所述)中明确表示。那可能吗?
2021-05-01 00:00:06
FWIW,我只是require为了简单起见在这里使用。没有什么可以阻止您使用import来获取value。至于类语法,不,ES6 没有提供一种方法来做到这一点(除了其他答案中所示的委托给函数的变通方法)。有一个关于类属性ES7 阶段 0 提议,你可以在其中编写class Foo { getColor = require('./getColor'); },但同样,在 ES6 中没有类似的东西。
2021-05-03 00:00:06
我想知道,为什么是静态方法。超集原型(不在实例上工作)方法不是他们的目的吗...
2021-05-10 00:00:06
@FelixKling 这个解决方案在反应中不起作用,请查看这个stackoverflow.com/questions/40603632/...
2021-05-18 00:00:06

如果您有兴趣,我开发了一个小module来将具有各种参数的函数绑定到类方法:https : //github.com/ngryman/to-method

const toMethod = require('to-method');

function Car(color) {
  this.color = color;
}

toMethod(Car, { getColor: require('./getColor') });