我试图了解范围如何与节点模块一起工作。我有一个IIFE来初始化一个LinkedList,它为每个元素使用Node对象 使用IIFE避免污染全球范围
在IIFE之后,节点在哪里?有什么办法可以在require对象即测试类中访问Node吗?
(function LinkedListInit() {
module.exports = new LinkedList();
function LinkedList() {
this.head;
}
// LinkedList Node
function Node(data, next) {
this.data = data;
this.next = next;
}
LinkedList.prototype.insert = insert;
function insert(data) {
var curr = this.head,
newNode = new Node(data);
if (this.head == null) {
this.head = newNode;
} else {
while (curr.next != null) {
curr = curr.next;
}
curr.next = newNode;
}
return this;
}
}());

var linkedList = require('../../js/ds/linkedList');
// Test cases for linkedList.insert(val); works fine.
// Can I access Node here?
答案 0 :(得分:3)
通常,ES6模块中定义的任何函数和变量都是模块范围的,即在这种情况下不需要IIFE。除非通过Node
明确导出,否则无法从模块外部访问insert
或module.exports
。
考虑到这一点,单元测试也无法简单地访问实现细节。如果您想单独测试Node
,最干净的方式可能会将其移至单独的模块并将其导入LinkedList
:
// Node.js
function Node(data, next) {
this.data = data;
this.next = next;
}
module.exports = Node;
// LinkedList.js
var Node = require('./Node');
function LinkedList() {
this.head;
}
LinkedList.prototype.insert = function(data) {
var curr = this.head,
newNode = new Node(data);
if (this.head == null) {
this.head = newNode;
} else {
while (curr.next != null) {
curr = curr.next;
}
curr.next = newNode;
}
return this;
}
module.exports = LinkedList;
// NodeTest.js
var Node = require('./Node');
var node = new Node('foo');
// ...
// LinkedListTest.js
var LinkedList = require('./LinkedList');
var linkedList = new LinkedList();
linkedList.insert('foo');
// ...
答案 1 :(得分:1)
在Node模块之外可以访问的唯一内容是添加到module.exports
变量的内容。
当你这样做时
var x = require('./some/path');
x将等于module.exports
中定义的./some/path.js
变量。
除非在Node
对象中以某种方式明确提供module.exports
,否则无法从模块文件外部访问它。
在Node中使用IIFE定义模块的典型方法是:
module.exports = (function() {
//...a lot of code...
return {
exportedValue1: somethingIWantToBeAvailable;
exportedValue2: aDifferentThing;
//... and so on ...
};
})();
但你真的不需要IIFE。与浏览器环境不同,如果显式地请求
,则只会将东西添加到节点中的全局范围内global.variable = something;
否则,您的变量位于 module-local 范围内。由于Node将模块和文件视为一一对应,这意味着您在文件中创建的任何变量只能在该文件中访问 - 禁止使用global
和module.exports
。
答案 2 :(得分:1)
您的范围已包含在模块中 - 除了您选择导出的内容,因此您不需要IIFE。
如果您希望它与IIFE一起使用,则必须将IIFE连接到module.exports
,而不是将IIFE包裹在其周围。有点像...
module.exports = (function LinkedListInit() {
function LinkedList() {
this.head;
}
return new LinkedList();
// ...