[英]socket undefined inside of socket.on
I have the current code; 我有当前代码;
socket.on('KeyPress', function(data){
var ply = PLAYER_LIST[socket.id];
/* ... */
});
WebStorm is informing me that socket.id may not be initialized, and then when this event is triggered it does cause the error WebStorm通知我未初始化socket.id,然后在触发此事件时确实导致了错误
TypeError: Cannot read property 'id' of undefined
The whole code is inside of 整个代码在内部
io.sockets.on('connection', function(socket){ /*...*/ });
Here is two of the on method I'm using; 这是我正在使用的两种on方法;
In the first block you can see I'm doing the same thing yet it works..
在第一个块中,您可以看到我正在做同样的事情,但它仍然有效。
Also on that note how secure is it to use socket.id to auth a user? 还要注意,使用socket.id对用户进行身份验证有多安全? Is it possible to force-set your own id?
是否可以强制设置自己的ID?
You are a victim of a bad practice of defining variables with var
within a loop and then getting bit by the influence of "variable hoisting" where a variable defined with var
anywhere in the function is automatically declared at the start of the function and then initialized where your assignment was, meaning it's undefined
everywhere in your function before that. 您是在循环中使用
var
定义变量,然后受“变量提升”的影响的错误做法的受害者,在变量“提升”中,在函数的任何位置使用var
定义的变量都会在函数开始时自动声明,然后初始化您的分配在哪里,这意味着在此之前函数中的每个地方都undefined
它。
The problem is this line of code: 问题是这行代码:
var socket = SOCKET_LIST[i];
That is redefining a local variable named socket
that hides the one you actually want. 那就是重新定义一个名为
socket
的局部变量,该变量隐藏了您真正想要的变量。 Variables defined with var
are function scoped. 用
var
定义的变量是函数范围的。 That means they are defined at the top of the function (this is called variable hoisting) and thus hides the other parent scoped socket
variable. 这意味着它们在函数的顶部定义(这称为变量提升),从而隐藏了其他父级作用域
socket
变量。
Think of your function as starting like this: 将您的函数想像成这样:
socket.on('KeyPress', function(data) {
var socket; // this is hoisted from deeper inside the function
// and creates a new undefined socket variable
var ply = PLAYER_LIST[socket.id];
// other code here
});
This is essentially how Javascript sees your code. 本质上,这就是Javascript看到您的代码的方式。 You can do a search on "Javascript variable hoisting" and see LOTS of articles written on the topic if you want more info.
您可以在“ Javascript变量提升”上进行搜索,如果需要更多信息,可以查看有关该主题的文章的全部内容。
The smallest change you can make it to change the name of this local variable to something else to it doesn't interfere with the parent scoped variable, but really this code structure is not ideal in the first place. 您可以进行的最小更改,以将该局部变量的名称更改为其他名称,从而不会干扰父范围变量,但是实际上,此代码结构首先并不理想。
var localSocket = SOCKET_LIST[i];
var ply = PLAYER_LIST[p];
localSocket.emit(...)
In general it's a bad practice to define a variable with var
inside a for
loop. 通常,在
for
循环内使用var
定义变量是一种不好的做法。 It leads to the "assumption" that it is scoped only to that loop, but in reality, it's scoped to the whole function and can mess with things outside of the loop. 它导致“假设”,它仅适用于该循环,但实际上,它适用于整个功能,并且可能使回路外的内容混乱。
In ES6, you can use let
or const
instead of var
to declare a variable that is actually scoped to only the block of the loop. 在ES6中,可以使用
let
或const
代替var
来声明一个变量,该变量实际上仅作用于循环块。
Of other note, you should NEVER be iterating arrays with for/in
. 另外要注意的是,永远不要使用
for/in
迭代数组。 That iterates all array properties (including other enumerable object properties), not just array elements. 这将迭代所有数组属性(包括其他可枚举的对象属性),而不仅仅是数组元素。 ES6 adds
for/of
for iterating arrays this way. ES6通过这种方式添加了
for/of
来迭代数组。 In ES5, you can use the more traditional for
loop or .forEach()
. 在ES5中,可以使用更传统的
for
循环或.forEach()
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.