Gọi một chức năng địa phương của người bản địa trong module.exports từ một chức năng khác trong module.exports?


326

Làm thế nào để bạn gọi một chức năng từ bên trong một chức năng khác trong một module.exportskhai báo?

app.js
var bla = require('./bla.js');
console.log(bla.bar());
bla.js
module.exports = {

  foo: function (req, res, next) {
    return ('foo');
  },

  bar: function(req, res, next) {
    this.foo();
  }

}

Tôi đang cố gắng truy cập chức năng footừ bên trong chức năng barvà tôi đang nhận được:

TypeError: Object # không có phương thức 'foo'

Nếu tôi đổi this.foo()thành chỉ foo()tôi nhận được:

ReferenceError: foo không được xác định


4
Tôi đã kiểm tra mã của bạn và không có lỗi. Hàm bar trả về không xác định vì không có câu lệnh return. Bạn có chắc là bạn đang kiểm tra chính xác?
Ferchi

1
Đã thử nghiệm trong phiên bản nút v8.12.0và không còn ném lỗi. barkhông có tuyên bố trả lại nên chạy console.log(bla.bar())đơn giản là trả vềundefined
VladNeacsu

Câu trả lời:


350

Thay đổi this.foo()thànhmodule.exports.foo()


1
@NamNguyen Gọi exports.foo()có vẻ hơi khó xử và khó đọc.
Afshin Mehrabani

4
Tôi nghĩ rằng điều này là tốt hơn so với câu trả lời được chấp nhận. Nếu bạn xác định các hàm bên ngoài phạm vi xuất, nó sẽ thêm một mức độ gián tiếp và đôi khi có thể mong muốn, điều đó làm cho nó phức tạp hơn, để tái cấu trúc, ví dụ đổi tên hàm, tìm cách sử dụng hàm, v.v.
Pierre Henry

1
một câu trả lời trực tiếp cho câu hỏi
Kermit_ice_tea

8
module.exports.foo()exports.foo()không hoạt động với tôi với Node.js v5.8.0.
giữa các

14
export.foo () không hoạt động nhưng module.exports.foo () đang hoạt động với NodeJS v6.9.1
R. Canser Yanbakan

191

Bạn có thể khai báo các chức năng của bạn bên ngoài module.exportskhối.

var foo = function (req, res, next) {
  return ('foo');
}

var bar = function (req, res, next) {
  return foo();
}

Sau đó:

module.exports = {
  foo: foo,
  bar: bar
}

11
Nếu tôi muốn truy cập các thuộc tính của đối tượng từ phương thức thì sao?
Rockstar5645

1
Tôi đang nhận TypeError: yourClass.youMethod không phải là một chức năng khi tôi làm điều này. Tôi đang sử dụng phiên bản nút 6.9.1. Bạn có phải có một tuyên bố trở lại? Tôi không có câu lệnh return vì tất cả mã của tôi không đồng bộ trong các hàm.
Brett Mathe

1
Đẹp so sánh các phong cách khác nhau - gist.github.com/kimmobrunfeldt/10848413
Tadas V.

Thực hiện rất tốt đẹp! +1
realnsleo

2
Hoặc, chính xác hơn là sử dụng ES6,module.exports = { foo, bar, }
Let Me Tink About It

118

Bạn cũng có thể làm điều này để làm cho nó ngắn gọn và dễ đọc hơn. Đây là những gì tôi đã thấy được thực hiện trong một số mô-đun nguồn mở được viết tốt:

var self = module.exports = {

  foo: function (req, res, next) {
    return ('foo');
  },

  bar: function(req, res, next) {
    self.foo();
  }

}

Phiên bản Node.js này có cụ thể không? Tôi đang thử điều này với v5.8.0 và nó đang đăng nhập không xác định.
giữa các

1
@doublejosh Bạn đã ... đọc câu hỏi chưa? Đó là hỏi làm thế nào bạn gọi một chức năng xuất từ ​​một chức năng khác. Nó không có gì để làm với các hạn chế truy cập.
Vụ kiện của Quỹ Monica

1
Có tôi đọc nó, xin vui lòng đọc lại. Câu trả lời này làm cho foo () được xuất với mô-đun, đi ngược lại điểm của hàm "cục bộ" chỉ được gọi trong mô-đun.
đôi

66

Bạn cũng có thể lưu tham chiếu đến phạm vi toàn cầu của mô-đun bên ngoài định nghĩa (mô-đun.) Export.somemodule:

var _this = this;

exports.somefunction = function() {
   console.log('hello');
}

exports.someotherfunction = function() {
   _this.somefunction();
}

Đó là giải pháp sạch hơn!
IvanZh

không cần _this và bạn chỉ có thể sử dụng cái này ở nơi bạn cần
Yuki

được sử dụng thistrực tiếp, không cần phải khai báo_this
Darius

1
Đề nghị đó hữu ích một khi thiskhông còn đúng thisnữa. (Lời hứa và cuộc gọi lại)
Andrew McOlash

Tôi thích giải pháp này tốt nhất vì nó cũng đưa ra một ví dụ về phạm vi trong các mô-đun NodeJS.
Miguelmorin

40

Một tùy chọn khác, và gần hơn với kiểu gốc của OP, là đặt đối tượng bạn muốn xuất thành một biến và tham chiếu biến đó để thực hiện các cuộc gọi đến các phương thức khác trong đối tượng. Sau đó, bạn có thể xuất biến đó và bạn tốt để đi.

var self = {
  foo: function (req, res, next) {
    return ('foo');
  },
  bar: function (req, res, next) {
    return self.foo();
  }
};
module.exports = self;

25
const Service = {
  foo: (a, b) => a + b,
  bar: (a, b) => Service.foo(a, b) * b
}

module.exports = Service

3
Điều này đặc biệt có thể sử dụng được vì mã của bạn đang có cuộc gọi Service.foo()và mã máy khách của bạn cũng sẽ được gọi Service.foo()với cùng một cách đặt tên.
Vince Bowdren

Đây là một câu trả lời hoàn hảo!
Jayant Varshney

16

Bắt đầu với Node.js phiên bản 13, bạn có thể tận dụng các Mô-đun ES6 .

export function foo() {
    return 'foo';
}

export function bar() {
    return foo();
}

Theo cách tiếp cận Lớp học:

class MyClass {

    foo() {
        return 'foo';
    }

    bar() {
        return this.foo();
    }
}

module.exports = new MyClass();

Điều này sẽ khởi tạo lớp chỉ một lần, do bộ nhớ đệm mô-đun của Node:
https://nodejs.org/api/modules.html#modules_caching


và làm thế nào để gọi một phương thức tĩnh với phương pháp này?
Plixxer

@CodeofGod Chỉ cần gọi nó như bạn sẽ gọi bất kỳ phương thức tĩnh nào khác. Trong trường hợp này, nếu foolà tĩnh, bạn sẽ gọi nó từ bên trong barnhư thế này : MyClass.foo().
m.spyratos

vâng tôi hiểu điều đó, nhưng làm thế nào bạn gọi nó từ một bộ điều khiển đang nhập nó như ... const oAccounts = quiries ("...");
Plixxer

Bạn có thể xuất lớp thực tế, không phải là một thể hiện của lớp. Bằng cách đó bạn có thể sử dụng các phương thức tĩnh của nó. Nếu sau đó bạn cần sử dụng các phương thức cá thể của nó, thì bạn sẽ phải khởi tạo lớp trong trình điều khiển của mình.
m.spyratos

6

Để khắc phục sự cố của bạn, tôi đã thực hiện một vài thay đổi trong bla.js và nó đang hoạt động,

var foo= function (req, res, next) {
  console.log('inside foo');
  return ("foo");
}

var  bar= function(req, res, next) {
  this.foo();
}
module.exports = {bar,foo};

và không sửa đổi trong app.js

var bla = require('./bla.js');
console.log(bla.bar());

1
Trong thanh chức năng, this.foo () không hoạt động ... nó cần phải là foo ()
Falcoa
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.