ES6/Node 4에서 인터페이스를 생성할 수 있는 방법이 있습니까?
ES6는 노드 4에서 완전히 사용할 수 있습니다.방법 계약을 정의하는 인터페이스 개념이 포함되어 있는지 궁금합니다.MyClass implements MyInterface
.
제 구글링으로는 많은 것을 찾을 수 없지만, 아마도 좋은 트릭이나 해결책이 있을 것입니다.
인터페이스는 ES6의 일부가 아니지만 클래스는 ES6의 일부입니다.
만약 당신이 그것들이 정말로 필요하다면, 당신은 그것들을 지원하는 TypeScript를 보아야 합니다.
이것이 그 문제에 대한 저의 해결책입니다.한 인터페이스를 다른 인터페이스로 재정의하여 여러 인터페이스를 '구현'할 수 있습니다.
class MyInterface {
// Declare your JS doc in the Interface to make it acceable while writing the Class and for later inheritance
/**
* Gives the sum of the given Numbers
* @param {Number} a The first Number
* @param {Number} b The second Number
* @return {Number} The sum of the Numbers
*/
sum(a, b) {
this._WARNING('sum(a, b)');
}
// delcare a warning generator to notice if a method of the interface is not overridden
// Needs the function name of the Interface method or any String that gives you a hint ;)
_WARNING(fName = 'unknown method') {
console.warn('WARNING! Function "' + fName + '" is not overridden in ' + this.constructor.name);
}
}
class MultipleInterfaces extends MyInterface {
// this is used for "implement" multiple Interfaces at once
/**
* Gives the square of the given Number
* @param {Number} a The Number
* @return {Number} The square of the Numbers
*/
square(a) {
this._WARNING('square(a)');
}
}
class MyCorrectUsedClass extends MyInterface {
// You can easy use the JS doc declared in the interface
/** @inheritdoc */
sum(a, b) {
return a + b;
}
}
class MyIncorrectUsedClass extends MyInterface {
// not overriding the method sum(a, b)
}
class MyMultipleInterfacesClass extends MultipleInterfaces {
// nothing overriden to show, that it still works
}
let working = new MyCorrectUsedClass();
let notWorking = new MyIncorrectUsedClass();
let multipleInterfacesInstance = new MyMultipleInterfacesClass();
// TEST IT
console.log('working.sum(1, 2) =', working.sum(1, 2));
// output: 'working.sum(1, 2) = 3'
console.log('notWorking.sum(1, 2) =', notWorking.sum(1, 2));
// output: 'notWorking.sum(1, 2) = undefined'
// but also sends a warn to the console with 'WARNING! Function "sum(a, b)" is not overridden in MyIncorrectUsedClass'
console.log('multipleInterfacesInstance.sum(1, 2) =', multipleInterfacesInstance.sum(1, 2));
// output: 'multipleInterfacesInstance.sum(1, 2) = undefined'
// console warn: 'WARNING! Function "sum(a, b)" is not overridden in MyMultipleInterfacesClass'
console.log('multipleInterfacesInstance.square(2) =', multipleInterfacesInstance.square(2));
// output: 'multipleInterfacesInstance.square(2) = undefined'
// console warn: 'WARNING! Function "square(a)" is not overridden in MyMultipleInterfacesClass'
편집:
코드를 개선하여 이제 간단하게 사용할 수 있습니다.implement(baseClass, interface1, interface2, ...)
에서extends
.
/**
* Implements any number of interfaces to a given class.
* @param cls The class you want to use
* @param interfaces Any amount of interfaces separated by comma
* @return The class cls exteded with all methods of all implemented interfaces
*/
function implement(cls, ...interfaces) {
let clsPrototype = Object.getPrototypeOf(cls).prototype;
for (let i = 0; i < interfaces.length; i++) {
let proto = interfaces[i].prototype;
for (let methodName of Object.getOwnPropertyNames(proto)) {
if (methodName !== 'constructor')
if (typeof proto[methodName] === 'function')
if (!clsPrototype[methodName]) {
console.warn('WARNING! "' + methodName + '" of Interface "' + interfaces[i].name + '" is not declared in class "' + cls.name + '"');
clsPrototype[methodName] = proto[methodName];
}
}
}
return cls;
}
// Basic Interface to warn, whenever an not overridden method is used
class MyBaseInterface {
// declare a warning generator to notice if a method of the interface is not overridden
// Needs the function name of the Interface method or any String that gives you a hint ;)
_WARNING(fName = 'unknown method') {
console.warn('WARNING! Function "' + fName + '" is not overridden in ' + this.constructor.name);
}
}
// create a custom class
/* This is the simplest example but you could also use
*
* class MyCustomClass1 extends implement(MyBaseInterface) {
* foo() {return 66;}
* }
*
*/
class MyCustomClass1 extends MyBaseInterface {
foo() {
return 66;
}
}
// create a custom interface
class MyCustomInterface1 {
// Declare your JS doc in the Interface to make it acceable while writing the Class and for later inheritance
/**
* Gives the sum of the given Numbers
* @param {Number} a The first Number
* @param {Number} b The second Number
* @return {Number} The sum of the Numbers
*/
sum(a, b) {
this._WARNING('sum(a, b)');
}
}
// and another custom interface
class MyCustomInterface2 {
/**
* Gives the square of the given Number
* @param {Number} a The Number
* @return {Number} The square of the Numbers
*/
square(a) {
this._WARNING('square(a)');
}
}
// Extend your custom class even more and implement the custom interfaces
class AllInterfacesImplemented extends implement(MyCustomClass1, MyCustomInterface1, MyCustomInterface2) {
/**
* @inheritdoc
*/
sum(a, b) {
return a + b;
}
/**
* Multiplies two Numbers
* @param {Number} a The first Number
* @param {Number} b The second Number
* @return {Number}
*/
multiply(a, b) {
return a * b;
}
}
// TEST IT
let x = new AllInterfacesImplemented();
console.log("x.foo() =", x.foo());
//output: 'x.foo() = 66'
console.log("x.square(2) =", x.square(2));
// output: 'x.square(2) = undefined
// console warn: 'WARNING! Function "square(a)" is not overridden in AllInterfacesImplemented'
console.log("x.sum(1, 2) =", x.sum(1, 2));
// output: 'x.sum(1, 2) = 3'
console.log("x.multiply(4, 5) =", x.multiply(4, 5));
// output: 'x.multiply(4, 5) = 20'
아래에 언급된 debiasej의 코멘트에서 debiasej는 설계 패턴(인터페이스, 클래스 기반)에 대해 더 자세히 설명합니다.
http://loredanacirstea.github.io/es6-design-patterns/
자바스크립트로 된 디자인 패턴 북은 당신에게 또한 유용할 수 있습니다:
http://addyosmani.com/resources/essentialjsdesignpatterns/book/
설계 패턴 = 클래스 + 인터페이스 또는 다중 상속
ES6 JS(실행할 노드 예제.js)의 공장 패턴 예:
"use strict";
// Types.js - Constructors used behind the scenes
// A constructor for defining new cars
class Car {
constructor(options){
console.log("Creating Car...\n");
// some defaults
this.doors = options.doors || 4;
this.state = options.state || "brand new";
this.color = options.color || "silver";
}
}
// A constructor for defining new trucks
class Truck {
constructor(options){
console.log("Creating Truck...\n");
this.state = options.state || "used";
this.wheelSize = options.wheelSize || "large";
this.color = options.color || "blue";
}
}
// FactoryExample.js
// Define a skeleton vehicle factory
class VehicleFactory {}
// Define the prototypes and utilities for this factory
// Our default vehicleClass is Car
VehicleFactory.prototype.vehicleClass = Car;
// Our Factory method for creating new Vehicle instances
VehicleFactory.prototype.createVehicle = function ( options ) {
switch(options.vehicleType){
case "car":
this.vehicleClass = Car;
break;
case "truck":
this.vehicleClass = Truck;
break;
//defaults to VehicleFactory.prototype.vehicleClass (Car)
}
return new this.vehicleClass( options );
};
// Create an instance of our factory that makes cars
var carFactory = new VehicleFactory();
var car = carFactory.createVehicle( {
vehicleType: "car",
color: "yellow",
doors: 6 } );
// Test to confirm our car was created using the vehicleClass/prototype Car
// Outputs: true
console.log( car instanceof Car );
// Outputs: Car object of color "yellow", doors: 6 in a "brand new" state
console.log( car );
var movingTruck = carFactory.createVehicle( {
vehicleType: "truck",
state: "like new",
color: "red",
wheelSize: "small" } );
// Test to confirm our truck was created with the vehicleClass/prototype Truck
// Outputs: true
console.log( movingTruck instanceof Truck );
// Outputs: Truck object of color "red", a "like new" state
// and a "small" wheelSize
console.log( movingTruck );
ECMA가 '계급 없는' 언어라는 점을 감안할 때, 고전적인 구성을 구현하는 것은 제가 보기에는 그다지 말이 되지 않습니다.위험은 그렇게 함으로써 효과적으로 언어를 재설계하려고 시도하고 있다는 것입니다(그리고, 그것에 대해 강하게 느낀다면, 앞서 언급한 TypeScript와 같은 휠 재창조를 완화하는 훌륭한 전체론적 솔루션이 있습니다).
그렇다고 해서 플레인 올드 JS에서 구성이 불가능하다는 것은 아닙니다.저는 얼마 전에 이것을 자세히 조사했습니다.객체 프로토타입 패러다임 내에서 구성을 다루는 가장 강력한 후보는 스탬프입니다. 현재 광범위한 프로젝트에서 사용하고 있습니다.그리고 중요한 것은, 그것이 잘 표현된 사양을 준수한다는 것입니다.
우표에 대한 더 많은 정보는 여기에 있습니다.
인터페이스를 시뮬레이션할 수 있는 패키지가 있습니다.
es6-interface를 사용할 수 있습니다.
흐름을 통해 전체 코드 기반을 TypeScript로 변환할 필요 없이 인터페이스를 지정할 수 있습니다.
인터페이스는 기존 코드 내에서 신중하게 진행하면서 종속성을 깨는 방법입니다.
언급URL : https://stackoverflow.com/questions/32626866/is-there-a-way-to-create-interfaces-in-es6-node-4
'programing' 카테고리의 다른 글
ASP를 통해 파일을 업로드하려면 어떻게 해야 합니까?NET MVC와 진행 표시줄을 표시하시겠습니까? (0) | 2023.07.26 |
---|---|
오라클 11g에 무제한 문자를 저장하는 방법은 무엇입니까? (0) | 2023.07.26 |
Spring + Web MVC: dispatcher-servlet.xml vs. applicationContext.xml (및 공유 보안) (0) | 2023.07.26 |
최대 절전 모드가 필드에 잘못된 유형을 설정하려고 합니다(Spring Data JPA). (0) | 2023.07.26 |
lazy-init에 대한 스프링 기본 동작 (0) | 2023.07.26 |