【问题标题】:Auto call function within Object once object is called?一旦对象被调用,对象内的自动调用函数?
【发布时间】:2020-06-22 13:57:17
【问题描述】:

我目前正在尝试找到一种方法,以允许对象中的函数在对象被调用后运行。

比如下面这个Object...

const textNodes = [
{
    id: 1,
    faction: "Greaser",
    text: "Do you want to help this person?",
    options: [
        {
            text: "Yes",
            nextText: 2
        },
        {
            text: "No",
            nextText: 2
        },
    ]
},
{
    id: 2,
    faction: "greaser",
    text: "It was a trap, do you run or kill them?",
    options: [
        {
            text: "Run",
            nextText: 3,
            damage: 0,
        },
        {
            text: "Kill",
            nextText: 5,
            damage: 8,
            moneyDrop: 20,
            radiationDamage: 2,
            logic: function update() {
                console.log("update function worked")

                if(character.greaser == true && this.faction == "greaser"){
                    console.log("greaser check worked");
                }

                character.health -= this.damage;
                character.cash += this.moneyDrop;
                character.radiationLevel += this.radiationDamage;
                character.maxHP -= this.radiationDamage;

                if(this.radiationDamage >= 1 ){
                    addRadiatedStatus();
                }

                console.log("character HP" + " " +  character.health);
                console.log("character maxHP" + " " +  character.maxHP);
                console.log("moneyDrop " + " " +  this.moneyDrop);
                console.log("character cash" + " " +  character.cash);
                console.log("radiation level" + " " +  character.radiationLevel);
                console.log("character Raditated?" + " " +  character.radiated);
            },
        },
    ]
}
]

如您所见,我有一个函数update(),一旦调用该函数,它将更改一个字符对象。

我目前正在调用该函数,例如... textNodes[1].options[1].logic();

当然,我不想这样做,因为我正在构建一个 rpg 决策游戏。用户将获得一个问题和一些选择,并允许创建自己的路径。如果用户得到 3 个选项,并且用户选择了选项 2,我将运行选项 2 的 logic() / update() 函数。

每个游戏选项都会附加一个功能,它会做不同的事情,每次我选择选项时,我都希望该功能自动运行。我不确定这是否可能,但这似乎是最合乎逻辑的选择。

我正在构建的纸牌决策游戏类似于https://www.youtube.com/watch?v=ByBUsBxPrZ4

正如您在此视频中看到的,每张选择的卡片(火种应用风格)都会更新游戏和角色统计数据。

我希望这些更新函数在调用对象选项后立即运行。我不确定这是否可能,一位同行告诉我my hint to you is to use classes,但我不经常使用类,除非我用 java 编码,坦率地说我不喜欢。

抱歉,如果这很难理解并提前致谢。


这是我尝试过的。

const textNodes = [
    {
        id: 1,
        faction: "Greaser",
        text: "Do you want to help this person?",
        options: [
           {
            text: "Yes",
            nextText: 2
           },
           {
            text: "No",
            nextText: 2
           },
        ]
    },
    {
        id: 2,
        faction: "greaser",
        text: "It was a trap, do you run or kill them?",
        options: [
           {
            text: "Run",
            nextText: 3,
            damage: 0,
           },
           {
            text: "Kill",
            nextText: 5,
            damage: 8,
            moneyDrop: 20,
            radiationDamage: 2,
            logic: function update(){
                console.log("update function worked")
                if(character.greaser == true && this.faction == "greaser"){
                    console.log("greaser check worked");
                }
            character.health -= this.damage;
            character.cash += this.moneyDrop;
            character.radiationLevel += this.radiationDamage;
            character.maxHP -= this.radiationDamage;
            if(this.radiationDamage >= 1 ){
                addRadiatedStatus();
            }
            console.log("character HP" + " " +  character.health);
            console.log("character maxHP" + " " +  character.maxHP);
            console.log("moneyDrop " + " " +  this.moneyDrop);
            console.log("character cash" + " " +  character.cash);
            console.log("radiation level" + " " +  character.radiationLevel);
            console.log("character Raditated?" + " " +  character.radiated);

            },
            run2:  () =>{
                this.logic();
            }
           },
        ]
    }
]

【问题讨论】:

  • 我觉得你可以帮忙proxy
  • 您能否详细说明“一旦调用对象选项”。 “叫”是什么意思?据我了解,您希望避免显式调用逻辑函数并自动调用它。我只是不明白触发器。
  • 你知道用户选择了哪个选项吗?如果是,您是否尝试直接在所选选项上调用 logic 方法?您甚至可以检查对象是否具有像这样定义的logic 属性:jsbin.com/nuyenagiwe/1/edit?js,console
  • @ΣπύροςΓούλας 感谢您的评论。当我的意思是“被调用”时,我的意思是每当用户为该问题 ID 选择一个“选项”时,我都想运行我的对象中的所有函数。因此,如果问题(id 2)是“你想跑还是打”,并且用户选择“打”选项,则该选项中的任何功能都将运行。如果用户选择战斗,也许我的函数会从玩家对象中减去生命值。我以本教程为起点,可能有助于理解我想要做什么。 youtube.com/watch?v=R1S_NhKkvGA&t=709s.

标签: javascript function oop


【解决方案1】:

最简单的方法是调用logic(又名update)在您希望在它们完成工作后进行更新的函数的末尾。

如果出于某种原因您不想这样做,您可以将它们包装在另一个可以执行此操作的函数中。创建textNodes后:

for (const {options} of textNodes) {
    for (const option of options) {
        const original = option.theOtherFunction;
        option.theOtherFunction = function(...args) {
            const result = original.apply(this, args);
            this.logic();
            return result;
        };
    }
}

现在,调用textNodes[i].options[1].theOtherFunction() 将完成theOtherFunction 的工作,然后调用logic(除非抛出错误)。

或者在 ES5 中:

textNodes.forEach(function(textNode) {
    textNode.options.forEach(function(option) {
        var original = option.theOtherFunction;
        option.theOtherFunction = function() {
            var result = original.apply(this, arguments);
            this.logic();
            return result;
        };
    });
});

从函数中重新调用this.logic,你可以看到它工作得很好:

const textNodes = [{
    id: 1,
    faction: "Greaser",
    text: "Do you want to help this person?",
    options: [{
        text: "Yes",
        nextText: 2
      },
      {
        text: "No",
        nextText: 2
      },
    ]
  },
  {
    id: 2,
    faction: "greaser",
    text: "It was a trap, do you run or kill them?",
    options: [{
        text: "Run",
        nextText: 3,
        damage: 0,
      },
      {
        text: "Kill",
        nextText: 5,
        damage: 8,
        moneyDrop: 20,
        radiationDamage: 2,
        logic: function update() {
          console.log("update function worked")
          /*
          if (character.greaser == true && this.faction == "greaser") {
            console.log("greaser check worked");
          }
          character.health -= this.damage;
          character.cash += this.moneyDrop;
          character.radiationLevel += this.radiationDamage;
          character.maxHP -= this.radiationDamage;
          if (this.radiationDamage >= 1) {
            addRadiatedStatus();
          }
          console.log("character HP" + " " + character.health);
          console.log("character maxHP" + " " + character.maxHP);
          console.log("moneyDrop " + " " + this.moneyDrop);
          console.log("character cash" + " " + character.cash);
          console.log("radiation level" + " " + character.radiationLevel);
          console.log("character Raditated?" + " " + character.radiated);
          */
        },
        run2: function() {
          console.log("This is run2");
          this.logic();
        }
      },
    ]
  }
];

textNodes[1].options[1].run2();

【讨论】:

  • 感谢您的回复 T.J.但是,我在这里有点困惑。我尝试在我的选项中添加一个名为runFunction: logic() 的键,但我得到了逻辑不存在的错误。我也试过this.logic,但也没有用。有没有办法做到这一点(不是你说“如果由于某种原因你不想这样做”后显示的方式,而是在最后添加函数调用)。
  • @ETHan - 为了进一步提供帮助,我需要一个问题的minimal reproducible example,不仅显示logic 的定义位置/方式,还显示您想要调用它的函数的位置/方式定义。如果它在 option 上,就像 logic 一样,this.logic(); 就可以了。
  • 我在这里定义逻辑logic: function update() { console.log("update function worked"),然后将另一个密钥对添加到该选项,如run: this.logic(),但这不起作用。让我发一个JS小提琴给你看。
  • @ETHan - 不,不是 jsFiddle。将回答问题所需的代码放入问题中,而不仅仅是链接。但是run: this.logic() 调用 this.logic() 将结果分配给run 属性,就像foo: 4242 分配给foo 属性一样。如果您打算将其作为一个函数,则必须创建一个函数:run: function() { this.logic(); }
  • 我编辑了帖子并添加了我一直在尝试做的事情。
猜你喜欢
  • 2020-10-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-17
  • 2021-03-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多