2013-03-08 64 views
5

Trong bất kỳ trình duyệt web nào thực hiện tập lệnh sau sẽ dẫn đến việc gửi 'wee' tới bảng điều khiển. Trong Nút, nó sẽ gửi {}.Vars được lưu trữ ở đâu trong Nodej?

var d = 'wee'; 
console.log(this.d); 

Tôi nhận thấy rằng trong Node this là đối tượng xuất trong trường hợp này. Tôi biết về biến số global và đó không phải là những gì tôi đang cố truy cập. Bên cạnh đó, tập lệnh ở trên cũng không đặt d trên đối tượng chung. Nó đi đâu vậy? Tôi có thể truy cập nó một cách rõ ràng bởi console.log(d); trong kịch bản ở trên nhưng nó dường như được cất giấu trong một số không gian tiêu chuẩn không có lý do gì cả.

Tôi cũng nhận ra rằng loại bỏ các var sẽ tuyên bố d trên đối tượng global, đó là hành vi mong đợi mặc dù nó có vẻ ngu ngốc để có var ở phạm vi cấp cao nhất lưu trữ các giá trị của nó ở một nơi khác với biến "trần truồng". Tôi có nghĩa là, không phải là điểm của hệ thống mô-đun được cho là một số loại dự phòng kỹ thuật số để bảo vệ chống lại ô nhiễm toàn cầu? Ở đây có vẻ như rất dễ dàng để phá vỡ các mô hình và rất khó khăn để làm một cái gì đó tiêu chuẩn.

d cũng không được khai báo trên đối tượng module.

Tôi không phải biện minh lý do tại sao tôi hỏi câu hỏi này nhưng tôi sẽ trả lời câu trả lời đầu tiên đi kèm với "nhưng tại sao bạn muốn làm taht hurr durrrr".

var d = {}; 
d.bleep = 'y'; 
var a = Object.keys(d); 

d.bloop = 'y'; 
d.blop = 'y'; 

var b = Object.keys(d); 

// c = b - a; 
var c = b.filter(function (item) { 
    if(a.indexOf(item) === -1) { 
     return true; 
    } 
    return false; 
}); 

console.log(a,b,c); 

Trong cùng một cách mà tôi có thể phân biệt giữa các quốc gia đối tượng nhất định d, tôi sẽ có thể phân biệt các tiểu bang về phạm vi cấp cao nhất. Trong trình duyệt, đây là đối tượng window, được tham chiếu bởi this trong phạm vi cấp cao nhất. Tôi sẽ có thể đánh lừa các thuộc tính của môi trường trước và sau khi thực thi kịch bản để xác định rất nhiều thứ, một trong số đó sẽ kiểm tra các hàm và các biến được khai báo trong phạm vi đầu của một tập lệnh tùy ý, sau đó chúng có thể được áp dụng cho đối tượng xuất khẩu. Điều này sẽ làm cho nó dễ dàng để programatically tạo giấy gói mô-đun cho các kịch bản mà không được viết như mô-đun với một đơn giản forEach áp dụng cho danh sách các hàm cấp cao nhất và các biến để gán whateverThisIs['varFunc'] để module.exports['varFunc'] ...

và các công cụ ...

Hành vi này có vẻ giống như một chức năng ẩn danh. Trong một hàm ẩn danh this có thể tham chiếu đến đối tượng window, var s sẽ phải được gọi trực tiếp (vì chúng nằm trong phạm vi của anon func) và các vars bị rò rỉ được khai báo mà không có từ khóa var có thể kết thúc ở đối tượng window. Tôi chưa đọc toàn bộ hướng dẫn, có lẽ đây chính xác là những gì đang diễn ra nhưng, tôi đã ấn tượng rằng mỗi mô-đun được thực hiện trong ngữ cảnh riêng của nó (cửa sổ) và Node đó đã truyền thông điệp giữa các ngữ cảnh mô-đun thông qua việc sử dụng globalmodule.exports ...

Tôi không biết. Tôi muốn biết mặc dù. Nếu bạn biết, hãy cho tôi biết.

+2

Nó đi trong phạm vi biến cục bộ. Trong một mô-đun, mã của bạn được bao bọc trong một hàm. Bạn chỉ không nhìn thấy nó, –

+0

Vì vậy, nó chỉ là một chức năng vô danh sau đó? Chắc chắn? – Kastor

+2

Có ... tôi cũng không nhớ nếu nó ẩn danh, nhưng điều đó không quan trọng. Nó là một hàm. Tham số đầu tiên được định nghĩa cho hàm là 'export', và một đối tượng rỗng được truyền cho tham số đó. Đối tượng tương tự được đặt làm giá trị 'this' của hàm. Bạn có thể kiểm tra điều này với 'console.log (đối số [0] === xuất, đối số [0] === this);', và bạn sẽ nhận được 'true' cho cả hai. –

Trả lời

10

Vì vậy, mỗi mô-đun nút được bọc như cơ thể của một hàm như shown here in the node source code

NativeModule.wrapper = [ 
    '(function (exports, require, module, __filename, __dirname) { ', 
    '\n});' 
]; 

Vì vậy, nếu bạn khai báo một biến với var, đó là chức năng địa phương để các mô-đun, về cơ bản một biến riêng cho module . Đây không phải là tài sản của global, module, module.exports hoặc this. Nếu bạn quên var, nó sẽ chuyển thành đối tượng global làm thuộc tính. Nếu bạn tạo thuộc tính một cách rõ ràng trên this, mã này sẽ chuyển thành exports và có sẵn cho các mô-đun khác.

Đây là một chương trình nhỏ được hy vọng là khai sáng.

var aDeclaredVar = '*aDeclaredVar*'; 
undeclaredVar = '*undeclaredVar*'; 
this.aThisProperty = '*aThisProperty*'; 
module.aModuleProperty = '*aModuleProperty*'; 
module.exports.anExportProperty = '*anExportProperty*'; 

console.log('this', this); 
console.log('this === exports', this === exports); 
console.log('this === module', this === module); 
console.log('this === module.exports', this === module.exports); 
console.log('aDeclaredVar', aDeclaredVar); 
console.log('undeclaredVar', undeclaredVar); 
console.log('this.aThisProperty', this.aThisProperty); 
console.log('module.aModuleProperty', module.aModuleProperty); 
console.log('module.exports.anExportProperty', module.exports.anExportProperty); 
console.log('global.undeclaredVar', global.undeclaredVar); 
console.log('global.aDeclaredVar', global.aDeclaredVar); 

Và đó là đầu ra:

this { aThisProperty: '*aThisProperty*', 
    anExportProperty: '*anExportProperty*' } 
this === exports true 
this === module false 
this === module.exports true 
aDeclaredVar *aDeclaredVar* 
undeclaredVar *undeclaredVar* 
this.aThisProperty *aThisProperty* 
module.aModuleProperty *aModuleProperty* 
module.exports.anExportProperty *anExportProperty* 
global.undeclaredVar *undeclaredVar* 
global.aDeclaredVar undefined 
+0

Cảm ơn bạn đã liên kết đến nguồn. : D Tôi chưa bao giờ thử xem xét các vars cục bộ của một hàm trước đây. Tôi không biết nếu có một hack để làm điều đó hay không, nhưng chắc chắn rằng hành vi tôi thấy làm cho cảm giác tốt bây giờ mà tôi biết bối cảnh. Nó giống như viết bookmarklets. – Kastor

+0

vì vậy tôi đã thử chạy một tập lệnh sẽ kết thúc trình bao bọc ...}; Tôi sẽ tìm một thứ khác để làm. : D – Kastor

+0

Cảm ơn bạn đã xóa thông tin này ... đã viết một phần mở rộng nút gốc và đã đấu tranh với điều này trong một vài ngày! +1 – jkp

Các vấn đề liên quan