具有require的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的模块结构结合使用?

假设您有一个班级,为了演示而希望使用模块,请说您想使用 fs

所以您创建文件:


Animal.js

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

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

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

这是正确的方法吗?

另外,如何将此类公开给节点项目中的其他文件?如果在单独的文件中使用它,您仍然可以扩展该类吗?

我希望你们中的一些人能够回答这些问题:)


3
就像对待ES6类名一样,只需对待ES6类名即可。他们是一样的。ES6语法只是语法糖,它创建了完全相同的基础原型,构造函数和对象。
jfriend00

无论如何,animalModule在拥有自己的模块作用域的节点模块中,创建您的IIFE 毫无意义。
Bergi

Answers:


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类名一样,只需对待ES6类名即可。他们是一样的。

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类与Node的常规CommonJS导出一起使用。无需将ES6导出语法与类一起使用。称之为The ES6 way有点误导。
loganfsmyth,2017年

2
是的,这是个人喜好。就个人而言,我只是为了语法一致性而使用importover require
范晋

2
是的,这是一种可靠的方法,我也这样做,请记住,Babel import与CommonJS模块的互操作方式不太可能最终在Node中工作,因此将来可能需要更改代码以与不带Babel的Node兼容。
loganfsmyth

4
ES6模块(导入和导出)仍在节点10中处于试验阶段,并且在启动节点时需要将其打开
触发

添加到@dorking的观点。Node 10.15.3是LTS(长期支持)版本,将持续到2020年4月。此处的其他详细信息: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来访问实际的类变量

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.