【问题标题】:object instance's properties crushed by another instance对象实例的属性被另一个实例粉碎
【发布时间】:2018-02-02 19:20:19
【问题描述】:

我是 node.js/javascript 的新手,来自 C# 世界:可能我的问题是将 C# 习惯转换为 javascript...

我创建了一个小型 node.js 应用程序来重现我遇到的问题。 在应用程序中,创建了两个“孩子”。他们每个人都抓住一个气球,并以或多或少的力量(参数)使其弹跳。当气球停止弹跳时,我们会从触发的事件中获取日志..

我的问题是第一个实例化的孩子似乎被最后一个粉碎了。暗恋似乎发生在调用“反弹”函数时。

这是我期待的日志序列:

  1. 迈克来到了花园。孩子想玩气球......
  2. Elia 来到了花园。孩子想玩气球......
  3. 确保 Mike 的名字是 Mike...
  4. 确保 Elia 的名字是 Elia...
  5. Mike 刚拿到一个气球,并在上面写下了他/她的名字!
  6. Mike 使气球弹起(力 10)!
  7. Elia 刚拿到一个气球,上面写着他/她的名字!
  8. Elia 使气球弹起(力 4)!
  9. Elia 的气球已经停止弹跳……上面写着 Elia。

10.Mike 的气球停止弹跳了……上面写着 Mike。

这是我得到的日志序列:

  1. 迈克来到了花园。孩子想玩气球......
  2. Elia 来到了花园。孩子想玩气球......
  3. 确保 Mike 的名字是 Mike...
  4. 确保 Elia 的名字是 Elia...
  5. Elia 刚拿到一个气球,并在上面写下了他/她的名字
  6. Elia 让气球弹起(力 10)
  7. Elia 刚拿到一个气球,上面写着他/她的名字!
  8. Elia 使气球弹起(力 4)!
  9. Elia 的气球已经停止弹跳……上面写着 Elia。

10.Elia 的气球已经停止弹跳了……上面写着 Elia 的名字

组成应用程序的三个文件。

app.js

const Kid = require('./kid.js');

var mike = new Kid('Mike');
var elia = new Kid('Elia');

console.log(`Ensure that Mike's name is ${mike.name}...`);
console.log(`Ensure that Elia's name is ${elia.name}...`);

mike.bounce(10);
elia.bounce(4);

kid.js

const Balloon = require('./balloon.js');
var self;

function Kid(name){
    self=this;
    this.name=name;

    console.log(`${this.name} arrived in the garden. The kid wants to play with a balloon....`);
}

Kid.prototype.bounce = function(force1To10) {
    var balloon = new Balloon(self.name); 
    balloon.bounce(force1To10);    
    balloon.on('balloonStopped',(kidnameWrittenOnIt)=>{
        console.log(`${self.name}'s balloon has stopped bouncing... The name written on it is ${kidnameWrittenOnIt}.`);
    });
};

module.exports=Kid;

balloon.js

const timers = require("timers");
var inherits = require('util').inherits;  
var EventEmitter = require('events').EventEmitter;
var self;

function Balloon(kidName) {
    self = this;
    this.kidName = kidName;

    this.bounce = function(kidsPower1To10){
        console.log(`${self.kidName} makes the balloon bounce (force ${kidsPower1To10}) !`);
        timers.setTimeout(() => {
            self.emit('balloonStopped',self.kidName);
        }, kidsPower1To10*1000); 
    }

    console.log(`${this.kidName} just got a balloon and wrote his/her name on it !`);
}

inherits(Balloon, EventEmitter);
module.exports = Balloon;

执行:

node app.js

提前感谢您提供任何有用的信息!

【问题讨论】:

标签: javascript node.js instance


【解决方案1】:

确实问题出在bounce 方法中。您引用了一个全局的 self 变量,该变量将引用第二个人。所以如果你在第一个人上调用bounce,它仍然会引用第二个人。

解决方法是直接使用this而不是self,或者在每个方法中定义self

function Kid(name){
    this.name=name;

    console.log(`${this.name} arrived in the garden. The kid wants to play with a balloon....`);
}

Kid.prototype.bounce = function(force1To10) {
    var balloon = new Balloon(this.name); 
    balloon.bounce(force1To10);
    balloon.on('balloonStopped',(kidnameWrittenOnIt)=>{
        console.log(`${this.name}'s balloon has stopped bouncing... The name written on it is ${kidnameWrittenOnIt}.`);
    });
};

现在您仍然需要注意,当您引用 bounce 方法时,请确保正确绑定 this。当您调用mike.bounce(10)elia.bounce(2) 时会出现这种情况,但是当您开始将bounce 方法分配给另一个变量并调用该另一个变量时会出现陷阱。在这种情况下,this 将是未定义的。

类符号

您也可以使用class 语法对上述代码进行编码:

class Kid {
    constructor(name) {
        this.name=name;
        console.log(`${this.name} arrived in the garden. The kid wants to play with a balloon....`);
    } 
    bounce(force1To10) {
        var balloon = new Balloon(this.name); 
        balloon.bounce(force1To10);
        balloon.on('balloonStopped',(kidnameWrittenOnIt)=>{
            console.log(`${this.name}'s balloon has stopped bouncing... The name written on it is ${kidnameWrittenOnIt}.`);
        });
    }
}

【讨论】:

  • 谢谢!我在kid.js和balloon.js中用这个替换了'self'变量,它确实有效。我将每个文件都视为一个类是错误的(就像我在 C# 中所做的那样);你的解释完全有道理。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-09
  • 2014-02-27
  • 2012-07-07
  • 1970-01-01
  • 2013-10-15
  • 2016-06-05
相关资源
最近更新 更多