引用导出属性的多种方式之间的差异

时间:2015-12-05 12:57:27

标签: javascript sockets socket.io

我使用socket.io并需要导出io对象以便在其他文件中使用。控制器A工作并成功发出消息。奇怪的是,控制器B和C没有正确引用.io。引用.io的三种方式之间有什么区别吗?

// index.js

exports.register = function (server, options, next) {
    var onlineUsers = {};

    var io = require('socket.io')(server.select('collaboration').listener);

    io.on('connection', function (socket) {
        socket.on('is_online', Handlers.is_online.bind(null, socket));
        socket.on('disconnect', Handlers.is_offline.bind(null, socket));
    });

    exports.io = io;

    next();
};

// controllerA.js
var io = require('./collaboration/index');
function testFunc() {
    io.io.emit('testing', {data: 'some data'});
}
// controllerB.js
var io = require('./collaboration/index').io;
function testFunc() {
    io.emit('testing', {data: 'some data'});
}
// controllerC.js
var index = require('./collaboration/index');
var io = index.io;
function testFunc() {
    io.emit('testing', {data: 'some data'});
}

1 个答案:

答案 0 :(得分:1)

这与时间有关:exports.io仅在调用register()时创建。在此之前,exports.io未定义。

这也反映在您的控制器中:

  • controllerA存储对exports index.js对象的引用。当您需要index.js时,exports.io尚不存在,但这不是问题,因为您稍后会在testFunc中引用它( 意味着必须在register()之前调用testFunc,否则io.io仍然未定义);
  • 在调用controllerB时,
  • controllerCexports.io直接引用require。那时候,它还不存在。换句话说,他们正在存储一个未定义的引用,因此他们的testFunc失败了;

以下是对正在发生的事情的简化:

// controllerA
var obj = {};
var io  = obj;
obj.io  = 'hello';
console.log(io.io);

// controllerB
var obj = {};
var io  = obj.io;
obj.io  = 'hello';
console.log(io);

// controllerC
var obj   = {};
var index = obj;
var io    = index.io;
obj.io    = 'hello';
console.log(io);

此日志:

hello
undefined
undefined