Các lớp ES6 của Node.js với yêu cầu


103

Vì vậy, cho đến nay, tôi đã tạo các lớp và mô-đun node.jstheo cách sau:

    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;

Bây giờ với ES6, bạn có thể tạo các lớp "thực tế" giống như sau:

class Animal{

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

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

Bây giờ, trước hết, tôi thích điều này :) nhưng nó đặt ra một câu hỏi. Làm thế nào để bạn sử dụng điều này kết hợp với node.jscấu trúc mô-đun của?

Giả sử bạn có một lớp học mà bạn muốn sử dụng một mô-đun để trình diễn, hãy nói rằng bạn muốn sử dụng fs

vì vậy bạn tạo tệp của mình:


Animal.js

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

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

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

Đây có phải là cách đúng đắn?

Ngoài ra, làm cách nào để bạn hiển thị lớp này với các tệp khác trong dự án nút của tôi? Và bạn vẫn có thể mở rộng lớp này nếu bạn đang sử dụng nó trong một tệp riêng?

Tôi hy vọng một số bạn sẽ có thể trả lời những câu hỏi này :)


3
Chỉ cần xử lý tên lớp ES6 giống như bạn đã xử lý tên phương thức khởi tạo theo cách ES5. Họ là một và giống nhau. Cú pháp ES6 chỉ là cú pháp và tạo chính xác nguyên mẫu, hàm tạo và các đối tượng cơ bản.
jfriend00

IIFE đó tạo ra của bạn animalModulelà khá vô nghĩa trong một mô-đun nút có phạm vi mô-đun riêng của nó.
Bergi

Câu trả lời:


156

Có, ví dụ của bạn sẽ hoạt động tốt.

Đối với việc hiển thị các lớp học của bạn, bạn có thể exportmột lớp học giống như bất kỳ thứ gì khác:

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

Hoặc ngắn hơn:

module.exports = class Animal {

};

Sau khi được nhập vào một mô-đun khác, bạn có thể coi nó như thể nó đã được xác định trong tệp đó:

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

class Cat extends Animal {
    ...
}

8
Bạn cũng có thể làm điều gì đó như module.exports = class Animal {}
Paul

điều đó đúng, tôi quên bạn có thể đặt tên cho mọi thứ trong khi phân công.
rossipedia

Nó phụ thuộc vào kiểu mã và sự rõ ràng. module.exportsthường được sử dụng cho xuất ẩn danh, trong khi exportđược sử dụng cho xuất có tên. Đây là một phép lịch sự khi viết mã cơ bản (bạn có thể nói), có thể hỗ trợ những người khác biết cách nhập lớp, mô-đun, v.v. của bạn.
greg.arnott

7
module.exports = Animal;sẽ là câu trả lời hoặc tương đương trực tiếp nhất với câu hỏi và hợp lệ cùng với const Animal = require('./animal');mã gọi điện. Bạn có thể cập nhật câu trả lời của mình để đưa vào không?
CN

1
Cảm ơn anh bạn, tôi đã chiến đấu với việc nhập lớp hoạt động chính xác trong 2 giờ.
kiwicomb123

11

Chỉ cần xử lý tên lớp ES6 giống như bạn đã xử lý tên phương thức khởi tạo theo cách ES5. Họ là một và giống nhau.

Cú pháp ES6 chỉ là cú pháp và tạo chính xác nguyên mẫu, hàm tạo và các đối tượng cơ bản.

Vì vậy, trong ví dụ ES6 của bạn với:

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

var a = new Animal();

module.exports = {Animal: Animal};

Bạn chỉ có thể coi Animalnhư hàm tạo của đối tượng của mình (giống như cách bạn đã làm trong ES5). Bạn có thể xuất hàm tạo. Bạn có thể gọi hàm tạo với new Animal(). Mọi thứ đều giống nhau để sử dụng nó. Chỉ khác nhau về cú pháp khai báo. Thậm chí vẫn có một Animal.prototypecó tất cả các phương pháp của bạn trên đó. Cách ES6 thực sự tạo ra cùng một kết quả mã hóa, chỉ với cú pháp đẹp hơn / đẹp hơn.


Về phía nhập khẩu, điều này sau đó sẽ được sử dụng như thế này:

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

let a = new Animal();

Lược đồ này xuất hàm tạo Animal dưới dạng thuộc .Animaltính cho phép bạn xuất nhiều thứ từ mô-đun đó.

Nếu bạn không cần xuất nhiều thứ, bạn có thể làm như sau:

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

module.exports = Animal;

Và sau đó nhập nó với:

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

let a = new Animal();

Tôi không biết tại sao nhưng điều này không hiệu quả với tôi. module.exports = Animallà giải pháp duy nhất hoạt động.
Sam

1
@Sam - Nội dung mà chương trình xuất của tôi cần khác require()với những gì mà chương trình xuất của bạn hiển thị, vì vậy đó sẽ là lý do tại sao một cái sẽ hoạt động và cái kia thì không. Bạn phải khớp cách nhập hoạt động với cách định nghĩa xuất. Thêm chi tiết để giải thích điều này đã được thêm vào câu trả lời của tôi.
jfriend00

5

Cách yêu cầu của ES6 là import. Bạn có thể exportnhập lớp của mình và nhập vào một nơi khác bằng import { ClassName } from 'path/to/ClassName'cú pháp.

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
Sẽ rất tốt nếu làm rõ rằng đây là một lựa chọn, nhưng không phải là một yêu cầu. Đây là cú pháp mô-đun ES6, nhưng bạn vẫn có thể sử dụng một lớp ES6 với các lần xuất CommonJS bình thường của Node. Không có yêu cầu bạn sử dụng cú pháp xuất ES6 với các lớp. Gọi nó The ES6 waylà hơi gây hiểu lầm.
loganfsmyth

2
Đó là sự thật, đó là sở thích cá nhân. Cá nhân, tôi sẽ sử dụng importhơn requirechỉ vì lợi ích của sự nhất quán về cú pháp.
Fan Jin

2
Vâng, đó là một cách tiếp cận chắc chắn và tôi cũng vậy, chỉ cần lưu ý rằng cách Babel importtương tác với các mô-đun CommonJS không có khả năng kết thúc hoạt động trong Node, vì vậy nó có thể yêu cầu thay đổi mã trong tương lai để tương thích với Node mà không có Babel .
loganfsmyth

4
ES6 module (xuất nhập khẩu) vẫn thực nghiệm trong Node 10 và cần phải được bật khi tung ra nút
dcorking

Để thêm vào quan điểm của @ dorking. Node 10.15.3 là phiên bản LTS (hỗ trợ dài hạn) và sẽ có cho đến tháng 4 năm 2020. Chi tiết bổ sung tại đây: nodejs.org/en/about/releases
gtzilla

1

Sử dụng các lớp trong nút -

Ở đây chúng ta đang yêu cầu mô-đun ReadWrite và gọi một makeObject (), trả về đối tượng của lớp ReadWrite. Mà chúng tôi đang sử dụng để gọi các phương thức. 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

Ở đây chúng ta tạo một phương thức makeObject, phương thức này đảm bảo rằng một đối tượng được trả về, chỉ khi một đối tượng không có sẵn.

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;

Để biết thêm giải thích, hãy truy cập https://medium.com/@nynptel/node-js-boiler-plate-code-using-singleton-classes-5b479e513f74


0

Trong tệp lớp, bạn có thể sử dụng:

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

hoặc bạn có thể sử dụng cú pháp này

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

module.exports = ClassNameHere;

Mặt khác, để sử dụng lớp này trong bất kỳ tệp nào khác, bạn cần thực hiện các bước sau. Trước tiên, yêu cầu tệp đó bằng cú pháp sau: const anyVariableNameHere = require('filePathHere');

Sau đó, tạo một đối tượng const classObject = new anyVariableNameHere();

Sau đó, bạn có thể sử dụng classObjectđể truy cập các biến lớp thực tế

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.