数组在方法范围内消失
arrays disappearing in method scope
我正在尝试为我的 javascript 游戏创建一个 class 以添加多人游戏,但在 class 中我遇到了数组值更改的问题,如您在sendNetEntities()
函数
class NET_IO{
//probably put address here
//I want to check for localhost to denote MASTER client
constructor(host, netlayer){
this.socket = io();
this.netLayer = netlayer
console.log(this.socket)
this.netEntities = this.netLayer.entities
//setInterval(() => {this.update()}, 200)
}
getNetEntities(){
this.socket.emit('getNetEntities', (net_entities) => {
console.log(net_entities)
this.netEntities = net_entities
})
}
sendNetEntities(layer){
var netEnt = this.netEntities
console.log(netEnt) //this returns [background: Entity, NIkTag: Entity, player: Entity]` the value i want
var ent = JSON.stringify(netEnt);
console.log(ent) //this returns []
this.socket.emit('sendNetEntities', ent)
}
update(layer, callback){
//check host if localhost dont retreive new data only send
this.sendNetEntities(layer)
callback(this.netEntities)
}
}
我认为我在变量以某种方式引用某物而不是实例时遇到了问题。但我不完全确定 javascript 背后的所有规则。谁能帮我阐明这个问题。我愿意根据需要编辑我的问题
编辑
进一步的调试使我相信 socket.io 一定是某种问题。如果我 运行 这个 this.socket.emit('sendNetEntities', {netEnt})
我在服务器上的 return 是 {netEnt:[]}
我以前在 socket.io 中没有遇到过这样的问题。难道我做错了什么。 socket.io 是问题所在
基于此:
//this returns [background: Entity, NIkTag: Entity, player: Entity]` the value i want
console.log(netEnt)
var ent = JSON.stringify(netEnt);
console.log(ent) //this returns []
我认为您将 Array
视为 Object
。在 JavaScript 中,这在技术上是可行的,因为几乎一切都是对象,包括数组。但是,这可能会导致意外行为:
// Create an array and an object
a = [] // an array
o = {} // an object
// Set some properties on both
a.p = 42
o.p = 42
// Show differences between arrays and objects:
console.log(a.constructor) // ƒ Array()
console.log(a) // [p: 42]
console.log(JSON.stringify(a)) // []
console.log(o.constructor) // ƒ Object()
console.log(o) // {p: 42}
console.log(JSON.stringify(o)) // {"p":42}
如您所见,JSON.stringify() 忽略了数组上设置的属性。
所以解决方案是使用 netEnt
作为数组或对象,不要混合类型:
// As an array, don't use property names. Use the integer array indices:
netEnt = [entity1, entity2, entity3]
background = netEnt[0]
nikTag = netEnt[1]
player = netEnt[2]
// As an object, property names can be used:
netEnt = {background: entity1, NIkTag: entity2, player: entity3}
background = netEnt.background
nikTag = netEnt.NIkTag
player = netEnt.player
更新:
根本问题是您的 classes 使用数组,但将它们作为对象访问。最好的解决方案是更改您的 classes,以便它们:
- 使用数组并将数组作为数组访问。
- 使用对象并将对象作为对象访问。
没有看到您的 class 定义,我无法向您展示如何执行此操作。然而,它就像将 class 个实例的初始值从 []
更改为 {}
.
一样简单
以下是将数组“对象”序列化为真正的 JS 对象的快速修复,因此 JSON.stringify() 将按预期工作。不过,以后我强烈推荐学习一下JS数组和对象的区别。这个快速修复带来了完全不必要的性能损失,因为 JS 数组被误用为对象:
sendNetEntities(layer){
var netEnt = this.netEntities
// Convert netEnt array "object" into true JS object
var trueObject = {}
for (prop in netEnt) {
trueObject[prop] = netEnt[prop]
}
var ent = JSON.stringify(trueObject);
this.socket.emit('sendNetEntities', ent)
}
请注意 getNetEntities()
,您可能必须执行相反的操作:将真正的 JS 对象转换回数组“对象”。我不确定 net_entities
的输入格式,所以我把它留作练习。
我正在尝试为我的 javascript 游戏创建一个 class 以添加多人游戏,但在 class 中我遇到了数组值更改的问题,如您在sendNetEntities()
函数
class NET_IO{
//probably put address here
//I want to check for localhost to denote MASTER client
constructor(host, netlayer){
this.socket = io();
this.netLayer = netlayer
console.log(this.socket)
this.netEntities = this.netLayer.entities
//setInterval(() => {this.update()}, 200)
}
getNetEntities(){
this.socket.emit('getNetEntities', (net_entities) => {
console.log(net_entities)
this.netEntities = net_entities
})
}
sendNetEntities(layer){
var netEnt = this.netEntities
console.log(netEnt) //this returns [background: Entity, NIkTag: Entity, player: Entity]` the value i want
var ent = JSON.stringify(netEnt);
console.log(ent) //this returns []
this.socket.emit('sendNetEntities', ent)
}
update(layer, callback){
//check host if localhost dont retreive new data only send
this.sendNetEntities(layer)
callback(this.netEntities)
}
}
我认为我在变量以某种方式引用某物而不是实例时遇到了问题。但我不完全确定 javascript 背后的所有规则。谁能帮我阐明这个问题。我愿意根据需要编辑我的问题
编辑
进一步的调试使我相信 socket.io 一定是某种问题。如果我 运行 这个 this.socket.emit('sendNetEntities', {netEnt})
我在服务器上的 return 是 {netEnt:[]}
我以前在 socket.io 中没有遇到过这样的问题。难道我做错了什么。 socket.io 是问题所在
基于此:
//this returns [background: Entity, NIkTag: Entity, player: Entity]` the value i want
console.log(netEnt)
var ent = JSON.stringify(netEnt);
console.log(ent) //this returns []
我认为您将 Array
视为 Object
。在 JavaScript 中,这在技术上是可行的,因为几乎一切都是对象,包括数组。但是,这可能会导致意外行为:
// Create an array and an object
a = [] // an array
o = {} // an object
// Set some properties on both
a.p = 42
o.p = 42
// Show differences between arrays and objects:
console.log(a.constructor) // ƒ Array()
console.log(a) // [p: 42]
console.log(JSON.stringify(a)) // []
console.log(o.constructor) // ƒ Object()
console.log(o) // {p: 42}
console.log(JSON.stringify(o)) // {"p":42}
如您所见,JSON.stringify() 忽略了数组上设置的属性。
所以解决方案是使用 netEnt
作为数组或对象,不要混合类型:
// As an array, don't use property names. Use the integer array indices:
netEnt = [entity1, entity2, entity3]
background = netEnt[0]
nikTag = netEnt[1]
player = netEnt[2]
// As an object, property names can be used:
netEnt = {background: entity1, NIkTag: entity2, player: entity3}
background = netEnt.background
nikTag = netEnt.NIkTag
player = netEnt.player
更新:
根本问题是您的 classes 使用数组,但将它们作为对象访问。最好的解决方案是更改您的 classes,以便它们:
- 使用数组并将数组作为数组访问。
- 使用对象并将对象作为对象访问。
没有看到您的 class 定义,我无法向您展示如何执行此操作。然而,它就像将 class 个实例的初始值从 []
更改为 {}
.
以下是将数组“对象”序列化为真正的 JS 对象的快速修复,因此 JSON.stringify() 将按预期工作。不过,以后我强烈推荐学习一下JS数组和对象的区别。这个快速修复带来了完全不必要的性能损失,因为 JS 数组被误用为对象:
sendNetEntities(layer){
var netEnt = this.netEntities
// Convert netEnt array "object" into true JS object
var trueObject = {}
for (prop in netEnt) {
trueObject[prop] = netEnt[prop]
}
var ent = JSON.stringify(trueObject);
this.socket.emit('sendNetEntities', ent)
}
请注意 getNetEntities()
,您可能必须执行相反的操作:将真正的 JS 对象转换回数组“对象”。我不确定 net_entities
的输入格式,所以我把它留作练习。