Классы Node.js ES6 с требованием


104

Итак, до сих пор я создавал классы и модули node.jsследующим образом:

    var fs = require('fs');

var animalModule = (function () {
    /**
     * Constructor initialize object
     * @constructor
     */
    var Animal = function (name) {
        this.name = name;
    };

    Animal.prototype.print = function () {
        console.log('Name is :'+ this.name);
    };

    return {
        Animal: Animal
    }
}());

module.exports = animalModule;

Теперь с ES6 вы можете создавать «настоящие» классы следующим образом:

class Animal{

 constructor(name){
    this.name = name ;
 }

 print(){
    console.log('Name is :'+ this.name);
 }
}

Сейчас, во-первых, мне это нравится :) но возникает вопрос. Как вы используете это в сочетании со node.jsструктурой модулей?

Скажем, у вас есть класс, в котором вы хотите использовать модуль для демонстрации, скажем, вы хотите использовать fs

поэтому вы создаете свой файл:


Animal.js

var fs = require('fs');
class Animal{

 constructor(name){
    this.name = name ;
 }

 print(){
    console.log('Name is :'+ this.name);
 }
}

Будет ли это правильный путь?

Кроме того, как предоставить этот класс другим файлам в моем проекте узла? И сможете ли вы расширить этот класс, если будете использовать его в отдельном файле?

Надеюсь, некоторые из вас ответят на эти вопросы :)


3
Просто обращайтесь с именем класса ES6 так же, как с именем конструктора в ES5. Они одно и то же. Синтаксис ES6 - это просто синтаксический сахар и создает точно такой же базовый прототип, функцию конструктора и объекты.
jfriend00 08

Тот IIFE, который создает ваш animalModule, довольно бессмысленен в модуле узла, который в любом случае имеет свою собственную область видимости.
Берги

Ответы:


160

Да, ваш пример подойдет.

Что касается раскрытия ваших классов, вы можете exportиспользовать класс, как и все остальное:

class Animal {...}
module.exports = Animal;

Или короче:

module.exports = class Animal {

};

После импорта в другой модуль вы можете рассматривать его так, как если бы он был определен в этом файле:

var Animal = require('./Animal');

class Cat extends Animal {
    ...
}

8
Вы также можете сделать что-то вроде module.exports = class Animal {}
Пол

это правда, я все время забываю, что вы можете давать имена во время задания.
rossipedia 09

Все сводится к стилю и ясности кода. module.exportsобычно используется для анонимного экспорта, тогда exportкак используется для именованного экспорта. Это базовая любезность кодирования (можно сказать), которая может помочь другим узнать, как импортировать ваш класс, модуль и т. Д.
greg.arnott 05

7
module.exports = Animal;будет ответом или наиболее прямым эквивалентом вопроса и действителен вместе с const Animal = require('./animal');вызывающим кодом. Можете ли вы обновить свой ответ, включив его?
вс

1
Спасибо, чувак, я боролся с правильной работой импорта классов около 2 часов.
kiwicomb123

11

Просто обращайтесь с именем класса ES6 так же, как с именем конструктора в ES5. Они одно и то же.

Синтаксис ES6 - это просто синтаксический сахар и создает точно такой же базовый прототип, функцию конструктора и объекты.

Итак, в вашем примере ES6 с:

// animal.js
class Animal {
    ...
}

var a = new Animal();

module.exports = {Animal: Animal};

Вы можете рассматривать его Animalкак конструктор вашего объекта (так же, как вы поступили бы в ES5). Вы можете экспортировать конструктор. Вы можете вызвать конструктор с помощью new Animal(). Все то же самое и с его использованием. Отличается только синтаксис объявления. Даже Animal.prototypeесть все ваши методы. Способ ES6 действительно дает тот же результат кодирования, только с более красивым / красивым синтаксисом.


На стороне импорта это будет использоваться следующим образом:

const Animal = require('./animal.js').Animal;

let a = new Animal();

Эта схема экспортирует конструктор Animal как .Animalсвойство, которое позволяет вам экспортировать более одного объекта из этого модуля.

Если вам не нужно экспортировать более одного объекта, вы можете сделать это:

// animal.js
class Animal {
    ...
}

module.exports = Animal;

А затем импортируйте его с помощью:

const Animal = require('./animal.js');

let a = new Animal();

Не знаю почему, но у меня это просто не сработало. module.exports = Animalэто единственное решение, которое работает.
Сэм

1
@Sam - То, что показывает мой экспорт, должно отличаться require()от того, что показывает ваш экспорт, поэтому одно будет работать, а другое - нет. Вы должны согласовать то, как работает импорт, с тем, как определяется экспорт. К моему ответу добавлены более подробные объяснения.
jfriend00

6

Способ запроса ES6 - import. Вы можете exportимпортировать свой класс в другое место, используя import { ClassName } from 'path/to/ClassName'синтаксис.

import fs from 'fs';
export default class Animal {

  constructor(name){
    this.name = name ;
  }

  print(){
    console.log('Name is :'+ this.name);
  }
}

import Animal from 'path/to/Animal.js';

4
Было бы хорошо уточнить, что это вариант, а не требование. Это синтаксис модуля ES6, но вы все равно можете использовать класс ES6 с обычным экспортом CommonJS в Node. Не требуется использовать синтаксис экспорта ES6 с классами. Называть это The ES6 wayнесколько неверно.
loganfsmyth 09

2
Это правда, это личное предпочтение. Лично я бы использовал importover requireтолько ради согласованности синтаксиса.
Fan Jin

2
Да, это солидный подход, и я тоже так делаю, просто имейте в виду, что способ importвзаимодействия Babel с модулями CommonJS маловероятно, что в конечном итоге будет работать в Node, поэтому в будущем может потребоваться изменение кода для совместимости с Node без Babel .
loganfsmyth 09

4
Модули ES6 (импорт и экспорт) все еще являются экспериментальными в Node 10 и должны быть включены при запуске узла
dcorking

Чтобы добавить к пункту @ dorking. Node 10.15.3 является версией LTS (долгосрочная поддержка) и будет действовать до апреля 2020 года. Дополнительная информация здесь: nodejs.org/en/about/releases
gtzilla

1

Использование классов в узле -

Здесь нам нужен модуль ReadWrite и вызывается makeObject (), который возвращает объект класса ReadWrite. Которые мы используем для вызова методов. index.js

const ReadWrite = require('./ReadWrite').makeObject();
const express = require('express');
const app = express();

class Start {
  constructor() {
    const server = app.listen(8081),
     host = server.address().address,
     port = server.address().port
    console.log("Example app listening at http://%s:%s", host, port);
    console.log('Running');

  }

  async route(req, res, next) {
    const result = await ReadWrite.readWrite();
    res.send(result);
  }
}

const obj1 = new Start();
app.get('/', obj1.route);
module.exports = Start;

ReadWrite.js

Здесь мы создаем метод makeObject, который гарантирует, что объект будет возвращен, только если объект недоступен.

class ReadWrite {
    constructor() {
        console.log('Read Write'); 
        this.x;   
    }
    static makeObject() {        
        if (!this.x) {
            this.x = new ReadWrite();
        }
        return this.x;
    }
    read(){
    return "read"
    }

    write(){
        return "write"
    }


    async readWrite() {
        try {
            const obj = ReadWrite.makeObject();
            const result = await Promise.all([ obj.read(), obj.write()])
            console.log(result);
            check();
            return result
        }
        catch(err) {
            console.log(err);

        }
    }
}
module.exports = ReadWrite;

Для получения дополнительных объяснений перейдите на https://medium.com/@nynptel/node-js-boiler-plate-code-using-singleton-classes-5b479e513f74.


0

В файле класса вы можете использовать:

module.exports = class ClassNameHere {
 print() {
  console.log('In print function');
 }
}

или вы можете использовать этот синтаксис

class ClassNameHere{
 print(){
  console.log('In print function');
 }
}

module.exports = ClassNameHere;

С другой стороны, чтобы использовать этот класс в любом другом файле, вам необходимо выполнить следующие действия. Сначала потребуйте этот файл, используя этот синтаксис: const anyVariableNameHere = require('filePathHere');

Затем создайте объект const classObject = new anyVariableNameHere();

После этого вы можете использовать classObjectдля доступа к фактическим переменным класса

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.