Node.js ES6 класи з попитом


103

Так що до цього часу я створював класи та модулі 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структурою модуля 's?

Скажімо, у вас є клас, де ви хочете використовувати модуль заради демонстрації, скажіть, що ви хочете використовувати 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

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

Відповіді:


156

Так, ваш приклад спрацював би чудово.

Що стосується експонування своїх класів, ви можете робити exportклас так само, як і будь-що інше:

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

Або коротше:

module.exports = class Animal {

};

Після імпорту в інший модуль ви можете ставитись до нього так, ніби він був визначений у цьому файлі:

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

class Cat extends Animal {
    ...
}

8
Ви також можете зробити щось на кшталт module.exports = class Animal {}
Павло

це правда, я постійно забуваю, що ви можете називати речі під час призначення.
rossipedia

Це зводиться до стилю та чіткості коду. module.exportsзазвичай використовується для анонімного експорту, тоді exportяк використовується для названого експорту. Це основна ввічливість (можна сказати) з кодування, яка може допомогти іншим дізнатись, як імпортувати свій клас, модуль та ін.
greg.arnott

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 дійсно створює той самий результат кодування, лише із синтаксисом fancier / nice.


Що стосується імпорту, то це буде використано так:

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

2
Це правда, це особисті переваги. Особисто я хотів би використовувати importбільш requireпросто заради синтаксису послідовності.
Вболівальник Джин

2
Так, це суцільний підхід, і я це також роблю, просто майте на увазі, що спосіб importвзаємодії Бабеля з модулями CommonJS, швидше за все, не призведе до того, що в кінцевому підсумку буде працювати в Node, тому це може зажадати зміни коду в майбутньому, щоб вони були сумісні з Node без Babel .
loganfsmyth

4
Модулі ES6 (імпорт та експорт) все ще експериментальні в Вузлі 10 і їх потрібно ввімкнути при запуску вузла
dcorking

Щоб додати до пункту @ dorking Вузол 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.