Javascript ES6 - 使用 import 语句在类上声明原型方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/32699889/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
ES6 - declare a prototype method on a class with an import statement
提问by SheedySheedySheedy
I am using ES6 classes. I want to be able to do this:
我正在使用 ES6 类。我希望能够做到这一点:
function Car(color) {
this.color = color;
};
Car.prototype.getColor = require('./getColor');
Where get color is an exported function. i.e. I want to be able to import a function from an outside file and set is as a prototype method on the ES6 Class. This is the kind of syntax I am talking about:
其中 get color 是一个导出函数。即我希望能够从外部文件导入一个函数,并将其设置为 ES6 类上的原型方法。这是我正在谈论的那种语法:
class Car {
constructor(color) {
this.color = color;
}
getColor() {} // I want to import this function from './getColor', as above
}
Is this doable?
这是可行的吗?
回答by ndugger
You can still attach a method on a class' prototype; after-all, classes are just syntactic sugar over a "functional object", which is the old way of using a function to construct objects.
你仍然可以在类的原型上附加一个方法;毕竟,类只是“功能对象”上的语法糖,这是使用函数构造对象的旧方法。
Since you want to use ES6, I'll use an ES6 import.
由于您想使用 ES6,我将使用 ES6 导入。
Minimal effort, using the prototype:
最小的努力,使用原型:
import getColor from 'path/to/module';
class Car {
...
}
Car.prototype.getColor = getColor;
As you can see, you still use the prototype property to attach a method, should you choose to.
如您所见,如果您愿意,您仍然使用原型属性来附加方法。
Calling the module within a class' method:
在类的方法中调用模块:
Alternatively, if you don't want to use the prototype property, you can always have your method return the function from the module:
或者,如果您不想使用原型属性,您始终可以让您的方法从模块返回函数:
import getColor from 'path/to/module';
class Car {
getColor () {
return getColor.call(this);
}
}
Using a Getter
使用吸气剂
You could also be a bit tricky and use a "getter" to achieve this in a different manner.
您也可能有点棘手,并使用“getter”以不同的方式实现这一点。
import getColor from 'path/to/module';
class Car {
get getColor () { return getColor.bind(this) }
}
You could then use it simply by calling, myInstanceOfCar.getColor()
然后你可以简单地通过调用来使用它, myInstanceOfCar.getColor()
Or in a more semantic usage of a getter:
或者在 getter 的更多语义用法中:
class Car {
get color () { return getColor.call(this) }
}
// ...
const color = myInstanceOfCar.color;
Keep in mind that getters/setters cannot have the same name as properties that you set in the constructor. You will end up exceeding the maximum call-stack with infinite recursion when you try to use the setter to set that same property. Example: set foo (value) { this.foo = value }
请记住,getter/setter 不能与您在构造函数中设置的属性同名。当您尝试使用 setter 来设置相同的属性时,最终会以无限递归超过最大调用堆栈。例子:set foo (value) { this.foo = value }
ES2016 Class Properties
ES2016 类属性
If you're using Babel to transpile(and are using experimental proposals), and want to use some ES2016, you can use the following syntax(but keep in mind that this applies the method to the object directly, and does not set it on the prototype):
如果您正在使用 Babel 进行转译(并且正在使用实验性提案),并且想要使用一些ES2016,您可以使用以下语法(但请记住,这将方法直接应用于对象,而不是将其设置为原型):
import getColor from 'path/to/module';
class Car {
getColor = getColor;
}
Optional binding w/ class properties
带有类属性的可选绑定
If you use the shorthand syntax for setting a property, you won't have to bind the method(setting is as a property changes what "this" refers to, essentially automatically binding it), but you certainly can, should you choose to (like if you'd like to bind something else):
如果您使用速记语法来设置属性,则不必绑定该方法(设置是作为属性更改“this”所指的内容,本质上是自动绑定它的),但是您当然可以,如果您选择(就像你想绑定其他东西一样):
getColor = getColor.bind(this);
回答by Felix Kling
Yes. The class
syntax is just (very sophisticated) syntactic sugar for constructor functions. So Car
will still be a function with a prototype
property and you can do exactly the same:
是的。该class
语法仅仅是(非常复杂)的构造函数的语法糖。所以Car
仍然是一个带有prototype
属性的函数,你可以做完全相同的事情:
import getColor from './getColor';
// ...
Car.prototype.getColor = getColor;
However, that makes the method enumerable, as opposed to the methods created from the class syntax. So you might want to use Object.defineProperty
instead.
然而,这使得方法可枚举,而不是从类语法创建的方法。所以你可能想Object.defineProperty
改用。
回答by ngryman
If you are interested, I've developed a little module to bind functions with various number of parameters to class methods: https://github.com/ngryman/to-method.
如果您有兴趣,我开发了一个小模块来将具有各种参数的函数绑定到类方法:https: //github.com/ngryman/to-method。
const toMethod = require('to-method');
function Car(color) {
this.color = color;
}
toMethod(Cat, { getColor: require('./getColor') });