Làm thế nào để sử dụng biến toàn cục trong node.js?


80

Ví dụ: tôi muốn sử dụng trình ghi tùy chỉnh:

logger = require('basic-logger'),
logger.setLevel('info')

var customConfig = {
showMillis: true,
showTimestamp: true
}

var log = new logger(customConfig)

Làm cách nào để sử dụng trình ghi này trong các mô-đun khác thay vì console.log?


2
thấy điều này bài stackoverflow.com/questions/4140661/...
— xvatar

1
Điều này có trả lời câu hỏi của bạn không? Biến toàn cục cho mô-đun tiêu chuẩn node.js?
— KyleMit

1
FYI Sử dụng global(chữ thường) thay vì GLOBAL(chữ hoa) mỗi cảnh báo deprecation nút của
— KyleMit

Câu trả lời:


118

Hầu hết mọi người khuyên không nên sử dụng các biến toàn cục. Nếu bạn muốn cùng một lớp trình ghi trong các mô-đun khác nhau, bạn có thể làm điều này

logger.js

  module.exports = new logger(customConfig);

foobar.js

  var logger = require('./logger');
  logger('barfoo');

Nếu bạn muốn một biến toàn cục, bạn có thể làm:

global.logger = new logger(customConfig);

29
KHÔNG sử dụng các biến toàn cục! Nếu bạn bắt đầu chạy ứng dụng của mình với nhiều quy trình, bạn sẽ gặp rắc rối rất nặng.
— TheHippo

32
TheHippo, các biến toàn cục là tốt trong một số trường hợp, ngay cả với nhiều quy trình. Ví dụ, một trình ghi nhật ký sẽ không có bất kỳ vấn đề nào nếu một số quy trình có phiên bản riêng của đối tượng trình ghi nhật ký.
— d512

145
Tôi chán khi thấy những bình luận về việc "không sử dụng hình cầu". Trong một số trường hợp, hình cầu là cách duy nhất để hoạt động. Tôi thường sử dụng nó để lưu trữ các giá trị không đổi, như "global.email = 'contact@domain.com'" và sử dụng nó trong toàn bộ dự án của mình. Nếu ngày mai tôi muốn thay đổi nó trong toàn bộ dự án, tôi chỉ cần thay đổi nó trong app.js (ví dụ Node, trong trường hợp này). Tôi không biết cách khác để thực hiện việc này trong Node ngoài việc sử dụng global. Vì vậy, xin vui lòng, không phân biệt nói "không sử dụng các biến toàn cục", chỉ nói "hãy khôn ngoan khi sử dụng toàn cầu".
— Eagle

37
@Eagle Tôi thực sự không hiểu tại sao bạn không thể nhập tệp cấu hình xác định biến email của bạn.
— Đón khách

29
Tôi có thể, nhưng khiếu nại của tôi không phải là liệu tôi có thể sử dụng tệp cấu hình hay không, mà là liệu tôi có thể sử dụng các vars chung theo cách an toàn hay không. Và tôi có thể.
— Eagle

50
global.myNumber; //Delclaration of the global variable - undefined
global.myNumber = 5; //Global variable initialized to value 5. 
var myNumberSquared = global.myNumber * global.myNumber; //Using the global variable. 

Node.js khác với JavaScript phía máy khách khi nói đến các biến toàn cục. Chỉ vì bạn sử dụng từ var ở đầu tập lệnh Node.js của mình không có nghĩa là tất cả các đối tượng bạn yêu cầu đều có thể truy cập được biến đó như 'basic-logger'.

Để tạo một cái gì đó toàn cục, chỉ cần đặt từ global và một dấu chấm ở phía trước tên của biến. Vì vậy, nếu tôi muốn company_id là toàn cầu, tôi gọi nó là global.company_id. Nhưng hãy cẩn thận, global.company_id và company_id giống nhau vì vậy đừng đặt tên biến toàn cục giống với bất kỳ biến nào khác trong bất kỳ tập lệnh nào khác - bất kỳ tập lệnh nào khác sẽ chạy trên máy chủ của bạn hoặc bất kỳ nơi nào khác trong cùng một mã .


1
Nó khác nhau bởi vì mỗi tệp / mô-đun được bao bọc ngầm trong một IIFE tại thời điểm xây dựng, vì vậy các vars thực sự là cục bộ của IIFE.
— siêu thường

28

bạn có thể xác định nó bằng cách sử dụng global hoặc GLOBAL, nodejs hỗ trợ cả hai.

ví dụ

global.underscore = require("underscore");

hoặc là

GLOBAL.underscore = require("underscore");

22

Tôi sẽ đề xuất mọi lúc khi sử dụng kiểm tra toàn cục nếu biến đã được xác định bằng cách đơn giản kiểm tra

if (!global.logger){
  global.logger = require('my_logger');
}

Tôi thấy nó có hiệu suất tốt hơn


@ wiktus239 Đây là một kiểm tra vì nó không yêu cầu mô-đun tải lại - Do đó hiệu suất tốt hơn.
— suprxd

2
Câu trả lời là ổn và ifcó thể được sử dụng để không xác định lại toàn cầu một cách không cần thiết, nhưng tôi muốn chỉ ra rằng requirekhông tải bất cứ thứ gì nhiều hơn một lần. Nó tải mọi thứ một lần và lưu kết quả vào bộ nhớ cache. Vì vậy, ifkhông bắt buộc phải tránh phân tích và tải mô-đun, nhưng sẽ hữu ích nếu bạn tránh gán lại giá trị từ bộ đệm nhiều lần.
— rsp

6

Các biến toàn cục có thể được sử dụng trong Node khi được sử dụng một cách khôn ngoan .

Khai báo các biến toàn cục trong Node:

a = 10;
GLOBAL.a = 10;
global.a = 10;

Tất cả các lệnh trên đều có các hành động giống nhau với các cú pháp khác nhau.

Sử dụng các biến toàn cục khi chúng không bị thay đổi

Dưới đây là một ví dụ về điều gì đó có thể xảy ra khi sử dụng các biến toàn cục:

// app.js
a = 10; // no var or let or const means global

// users.js
app.get("/users", (req, res, next) => {
   res.send(a); // 10;
});

// permissions.js
app.get("/permissions", (req, res, next) => {
   a = 11; // notice that there is no previous declaration of a in the permissions.js, means we looking for the global instance of a.
   res.send(a); // 11;
});

Giải thích:

Chạy tuyến người dùng trước và nhận 10;

Sau đó chạy các tuyến đường quyền và nhận được 11;

Sau đó, chạy lại định tuyến người dùng và nhận 11 thay vì 10;

Các biến toàn cục có thể bị vượt qua!

Bây giờ hãy nghĩ về việc sử dụng đối tượng res express và gán như toàn cục .. Và bạn sẽ gặp phải lỗi async trở nên bị hỏng và máy chủ bị tắt.

Khi nào sử dụng vars toàn cầu?

Như tôi đã nói - khi var không bị thay đổi. Tuy nhiên, bạn nên sử dụng process.envđối tượng từ tệp cấu hình.


4

Có thể sau là tốt hơn để tránh iftuyên bố:

global.logger || (global.logger = require('my_logger'));

5
global.logger = global.logger || require('my_logger')
— Jake Wilson,

3

Nếu ứng dụng của bạn được viết bằng TypeScript, hãy thử

(global as any).logger = // ...

hoặc là

Object.assign(global, { logger: // ... })

Tuy nhiên, tôi sẽ chỉ làm điều đó khi React Native đang __DEV__ở trong môi trường thử nghiệm.

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 cookie và Chính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.