Reputation: 111
It took me a while to figure out what the problem was, but I'm wondering why it's acting like that.
Using this code, the variables player, players and socket will be undefined, causing errors.
var player = Player(socket.id, socket);
socket.on('joinHost', function(data) {
var gameID = data;
player.gameID=gameID;
var game = GAME_LIST[gameID];
game.players[socket.id]=player;
var players = game.players;
for (var p in players){
var player = players[p];
var socket = player.socket;
socket.emit('playerJoined');
}
});
Avoiding the declarations of variables with same names makes it all work correctly.
var player = Player(socket.id, socket);
socket.on('joinHost', function(data) {
var gameID = data;
player.gameID=gameID;
var game = GAME_LIST[gameID];
game.players[socket.id]=player;
var tempPlayers = game.players;
for (var p in tempPlayers){
var tempPlayer = tempPlayers[p];
var tempSocket = tempPlayer.socket;
tempSocket.emit('playerJoined');
}
});
The interesting part is, when I ran the first code, it says the player in the line player.gameID=gameID
is undefined, while if I removed the code which is after player.gameID=gameID
, the player was defined. Basically, the code after player.gameID=gameID
caused the player to be undefined.
So, why is this happening?
Upvotes: 1
Views: 77
Reputation: 1017
Javascript moves variables's declaration to the top of the scope they were defined and gives them an undefined initial value but keeps assignment in place. This is called hoisting
Your code is equivalent to :
var player = Player(socket.id, socket);
socket.on('joinHost', function(data) {
var gameID; // undefined
var game; // undefined
var players; // undefined
var player; // undefined
var socket; // undefined
gameID = data;
player.gameID=gameID; // can't set property 'gameID' of undefined
game = GAME_LIST[gameID];
game.players[socket.id]=player; // is undefined since 'player' is undefined at this stage
players = game.players; // undefined
for (var p in players){
player = players[p];
socket = player.socket;
socket.emit('playerJoined');
}
});
Upvotes: 1
Reputation: 856
When you declare var player = players[p];
it is declared for the whole function scope (the for loop doesn't has a scope of it's own).
The names in the current scope are evaluated all in the beginning, before executing the function body.
So when function(data)
is called, the name player
is overridden in that scope even before var gameID = data;
is executed.
A minimal example:
> var x = 'foo';
> f = function() { console.log(x); var x = 'bar'; }
> f()
undefined
Upvotes: 2