数组在方法范围内消失

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 的输入格式,所以我把它留作练习。