Javascript 在模块内部实例化类时超出了最大调用堆栈
第7行我的console.log打印得很好 host.jsJavascript 在模块内部实例化类时超出了最大调用堆栈,javascript,node.js,npm,Javascript,Node.js,Npm,第7行我的console.log打印得很好 host.js "use strict"; var engine = require('./engine.js'); var base = require('./base.js'); var player = new base.Avatar(); console.log(player.x); class PillarGame extends engine.ServerGame { connectPlayer(socket) {
"use strict";
var engine = require('./engine.js');
var base = require('./base.js');
var player = new base.Avatar();
console.log(player.x);
class PillarGame extends engine.ServerGame {
connectPlayer(socket) {
var player = new base.Avatar();
this.add('players', player);
console.log("added player");
//announce
}
}
module.exports = {'HostedGame' : PillarGame};
但在创建该对象并发出以下信息后,我的服务器发生了崩溃:
if (obj.hasOwnProperty(key) && _hasBinary(obj[key])) {
^
RangeError: Maximum call stack size exceeded
at Object.hasOwnProperty (native)
为什么会崩溃
base.js没有任何要求
堆栈跟踪:
listening
connected
added player
/Users/quantum/code/online/node_modules/socket.io/node_modules/has-binary-data/index.js:0
(function (exports, require, module, __filename, __dirname) { /*
RangeError: Maximum call stack size exceeded
at _hasBinary (/Users/quantum/code/online/node_modules/socket.io/node_modules/has-binary-data/index.js:24:22)
at _hasBinary (/Users/quantum/code/online/node_modules/socket.io/node_modules/has-binary-data/index.js:37:15)
at _hasBinary (/Users/quantum/code/online/node_modules/socket.io/node_modules/has-binary-data/index.js:47:40)
at _hasBinary (/Users/quantum/code/online/node_modules/socket.io/node_modules/has-binary-data/index.js:47:40)
at _hasBinary (/Users/quantum/code/online/node_modules/socket.io/node_modules/has-binary-data/index.js:47:40)
at _hasBinary (/Users/quantum/code/online/node_modules/socket.io/node_modules/has-binary-data/index.js:37:15)
at _hasBinary (/Users/quantum/code/online/node_modules/socket.io/node_modules/has-binary-data/index.js:47:40)
at _hasBinary (/Users/quantum/code/online/node_modules/socket.io/node_modules/has-binary-data/index.js:47:40)
at _hasBinary (/Users/quantum/code/online/node_modules/socket.io/node_modules/has-binary-data/index.js:47:40)
at _hasBinary (/Users/quantum/code/online/node_modules/socket.io/node_modules/has-binary-data/index.js:37:15)
server.js,在上崩溃
socket.emit(“game.things”,game.things)代码>
var express=require('express');
var path=require('path');
var-app=express();
var server=require('http')。createServer(应用程序);
var io=require('socket.io')(服务器);
变量逻辑=要求('./逻辑');
var hostedGame=require('./host');
var game=newhostedgame.hostedGame({'sockets':io.sockets});
app.use(express.static(path.join(uu dirname,'public'));
监听(3000,函数(){
console.log('listing');
});
io.on('连接',函数(套接字){
console.log('connected');//extrac
游戏。连接播放器(插座);
//console.log(“game.things['players']”+game.things['players']);;
socket.emit(“game.things”,game.things);
//socket.on('input',函数(数据){
//游戏。输入(套接字、数据);
// });
});
var loopAsync=函数(){
设置超时(循环,10);
//setImmediate(循环);
}
var now=Date.now();
var last=现在;
var dt=0.00;
var率=10;
函数循环(){
now=Date.now();
var delta=现在-最后一次;
最后=现在;
dt=dt+delta;
如果(dt<速率){
loopAsync();
返回;
}否则{
dt-=速率;
//如果dt仍然>速率,则在为真时重复以下步骤
var updates=game.loop();
//放出东西
io.sockets.emit('player-positions',logic.player);
//输入输出到特定的播放器
loopAsync();
}
}
loopAsync();
base.js
"use strict";
class Component {
defaultMaxCharge() {
return [0];
}
constructor(options) {
options = options || {};
this.charge = [0];
if (options['maxCharge']) {
this.maxCharge = options['maxCharge'];
} else {
this.maxCharge = this.defaultMaxCharge();
}
}
loop() {
}
getValue(name, hash) {
return hash;
}
}
class Looper extends Component {
registrationNames() {
return ['loop'];
}
}
class Mover extends Looper {
loop() {
var velocity = this.thing.getValue('velocity');
var speed = this.thing.getValue('speed')['speed'];
var total = Math.abs(velocity.vx) + Math.abs(velocity.vy);
if (total <= 0) {
return;
}
var xx = velocity.mx / total * this.speedMod();
var yy = velocity.my / total * this.speedMod();
this.thing.x = this.thing.x + xx * speed;
this.thing.y = this.thing.y + yy * speed;
this.thing.x += velocity.vx;
this.thing.y += velocity.vy; //announce
}
}
//input components
class XWalker extends Component {
constructor(options) {
super(options);
this.vx = 0;
}
registrationNames() {
return ['input', 'velocity'];
}
getValue(name, hash) {
if (name == 'velocity') {
hash.vx = this.vx; //times speed
}
return hash;
}
processEvent(name, eventer, hash) {
if (name == 'input') {
if (hash.left) {
this.vx = -1;
} else if (hash.right) {
this.vx = 1;
} else {
this.vx = 0;
}
}
}
}
class YWalker extends Component {
constructor(options) {
super(options);
this.vx = 0;
}
registrationNames() {
return ['input', 'velocity'];
}
getValue(name, hash) {
if (name == 'velocity') {
hash.vy = this.vy; //times speed
}
return hash;
}
processEvent(name, eventer, hash) {
if (name == 'input') {
if (hash.up) {
this.vy = -1;
} else if (hash.down) {
this.vy = 1;
} else {
this.vy = 0;
}
}
}
}
class Thing {
spawnComponents(options) {
return [];
}
installComponents(options) {
this.componentRegistrations = {};
this.components = [];
var comps = this.spawnComponents(options);
for (var i = 0; i < comps.length; i++) {
var component = comps[i];
component.thing = this;
this.registerComponent(component);
this.components.push(component);
}
}
registerComponent(component) {
for (var i = 0; i < component.registrationNames().length; i++) {
var eventName = component.registrationNames()[i];
if (!this.componentRegistrations[eventName]) {
this.componentRegistrations[eventName] = [];
}
this.componentRegistrations[eventName].push(component);
}
}
getValue(name) {
var registered = this.componentRegistrations[name];
if (registered) {
var valueHash = {};
for (var i = 0; i < registered.length; i++) {
var component = registered[i];
valueHash = component.getValue(name, valueHash);
if (valueHash.stop) {
return valueHash;
}
}
return valueHash;
}
}
processEvent(name, eventer, hash) {
var registered = this.componentRegistrations[name];
if (registered) {
for (var i = 0; i < registered.length; i++) {
var component = registered[i];
component.processEvent(name, eventer, hash);
}
}
}
constructor(options) {
if (options && options['position']) {
this.x = options['position'].x * this.canvas.width;
this.y = options['position'].y * this.canvas.height;
} else {
this.x = 2.0;
this.y = 2.0;
}
this.installComponents(options);
this.active = true;
}
loop() {
for (var i = 0; i < this.components.length; i++) {
var component = this.components[i];
component.loop();
}
}
afterLoop() {
}
position() {
return {'x' : this.x, 'y' : this.y};
}
}
class Avatar extends Thing {
spawnComponents(options) {
return [new Mover(), new XWalker(), new YWalker()];
}
}
module.exports = {'Component' : Component, 'Thing' : Thing,
'Mover' : Mover, 'Looper' : Looper, 'XWalker' : XWalker, 'YWalker' : YWalker,
'Avatar' : Avatar};
“严格使用”;
类组件{
defaultMaxCharge(){
返回[0];
}
构造函数(选项){
选项=选项| |{};
这个.电荷=[0];
如果(选项['maxCharge']){
this.maxCharge=options['maxCharge'];
}否则{
this.maxCharge=this.defaultMaxCharge();
}
}
循环(){
}
getValue(名称、哈希){
返回散列;
}
}
类循环器扩展组件{
注册名称(){
返回['loop'];
}
}
类移动器扩展了Looper{
循环(){
var-velocity=this.thing.getValue('velocity');
var speed=this.thing.getValue('speed')['speed'];
var total=Math.abs(velocity.vx)+Math.abs(velocity.vy);
如果(总计)
最有可能的是游戏。
是一个具有循环引用的复杂对象,socket.io在发出之前试图将其转换为JSON,但失败。也许你应该发布完整的回溯输出?你也可以发布base.Avatar
的实现。啊,搞定了。注销对象并看到“循环”在参考资料中。
"use strict";
class Component {
defaultMaxCharge() {
return [0];
}
constructor(options) {
options = options || {};
this.charge = [0];
if (options['maxCharge']) {
this.maxCharge = options['maxCharge'];
} else {
this.maxCharge = this.defaultMaxCharge();
}
}
loop() {
}
getValue(name, hash) {
return hash;
}
}
class Looper extends Component {
registrationNames() {
return ['loop'];
}
}
class Mover extends Looper {
loop() {
var velocity = this.thing.getValue('velocity');
var speed = this.thing.getValue('speed')['speed'];
var total = Math.abs(velocity.vx) + Math.abs(velocity.vy);
if (total <= 0) {
return;
}
var xx = velocity.mx / total * this.speedMod();
var yy = velocity.my / total * this.speedMod();
this.thing.x = this.thing.x + xx * speed;
this.thing.y = this.thing.y + yy * speed;
this.thing.x += velocity.vx;
this.thing.y += velocity.vy; //announce
}
}
//input components
class XWalker extends Component {
constructor(options) {
super(options);
this.vx = 0;
}
registrationNames() {
return ['input', 'velocity'];
}
getValue(name, hash) {
if (name == 'velocity') {
hash.vx = this.vx; //times speed
}
return hash;
}
processEvent(name, eventer, hash) {
if (name == 'input') {
if (hash.left) {
this.vx = -1;
} else if (hash.right) {
this.vx = 1;
} else {
this.vx = 0;
}
}
}
}
class YWalker extends Component {
constructor(options) {
super(options);
this.vx = 0;
}
registrationNames() {
return ['input', 'velocity'];
}
getValue(name, hash) {
if (name == 'velocity') {
hash.vy = this.vy; //times speed
}
return hash;
}
processEvent(name, eventer, hash) {
if (name == 'input') {
if (hash.up) {
this.vy = -1;
} else if (hash.down) {
this.vy = 1;
} else {
this.vy = 0;
}
}
}
}
class Thing {
spawnComponents(options) {
return [];
}
installComponents(options) {
this.componentRegistrations = {};
this.components = [];
var comps = this.spawnComponents(options);
for (var i = 0; i < comps.length; i++) {
var component = comps[i];
component.thing = this;
this.registerComponent(component);
this.components.push(component);
}
}
registerComponent(component) {
for (var i = 0; i < component.registrationNames().length; i++) {
var eventName = component.registrationNames()[i];
if (!this.componentRegistrations[eventName]) {
this.componentRegistrations[eventName] = [];
}
this.componentRegistrations[eventName].push(component);
}
}
getValue(name) {
var registered = this.componentRegistrations[name];
if (registered) {
var valueHash = {};
for (var i = 0; i < registered.length; i++) {
var component = registered[i];
valueHash = component.getValue(name, valueHash);
if (valueHash.stop) {
return valueHash;
}
}
return valueHash;
}
}
processEvent(name, eventer, hash) {
var registered = this.componentRegistrations[name];
if (registered) {
for (var i = 0; i < registered.length; i++) {
var component = registered[i];
component.processEvent(name, eventer, hash);
}
}
}
constructor(options) {
if (options && options['position']) {
this.x = options['position'].x * this.canvas.width;
this.y = options['position'].y * this.canvas.height;
} else {
this.x = 2.0;
this.y = 2.0;
}
this.installComponents(options);
this.active = true;
}
loop() {
for (var i = 0; i < this.components.length; i++) {
var component = this.components[i];
component.loop();
}
}
afterLoop() {
}
position() {
return {'x' : this.x, 'y' : this.y};
}
}
class Avatar extends Thing {
spawnComponents(options) {
return [new Mover(), new XWalker(), new YWalker()];
}
}
module.exports = {'Component' : Component, 'Thing' : Thing,
'Mover' : Mover, 'Looper' : Looper, 'XWalker' : XWalker, 'YWalker' : YWalker,
'Avatar' : Avatar};
server.js, crashes on socket.emit("game.things", game.things);