【问题标题】:Javascript Array of Instances of a class类的实例的Javascript数组
【发布时间】:2019-02-21 22:41:02
【问题描述】:

在 JS 中,我有一个名为 player 的类:

class player {
    constructor(name) {
        this.name = name;
    }
}

我有两个实例,分别称为 PL1PL2

const PL1 = new player ('pl1name');
const PL2 = new player ('pl2name');

我还有一个名为PLAYERS的数组:

let PLAYRES = [];

现在,问题是如何创建一个包含所有 player 类实例的数组?

我知道我可以使用 PLAYERS.push(PLn) 手动执行此操作;但我正在寻找一种以某种方式自动执行此操作的方法。有内置功能吗?我应该使用循环吗?

【问题讨论】:

    标签: javascript class object


    【解决方案1】:

    通过将我的类更改为创建新实例时,我找到了这样做的答案:

    class player {
        constructor(name){
            this.name = name;
            PLAYERS.push(this);
        }
    }
    

    【讨论】:

      【解决方案2】:

      要使用静态数量的Player 对象初始化一个数组,您可以在数组中调用new Player()

      const players = [new Player('name1'), new Player('name2'), new Player('name3')];
      

      您还可以使用循环动态创建玩家列表:

      const playerNames = ['name1', 'name2', 'name3'];
      let players = [];
      playerNames.forEach((playerName) => players.push(new Player(playerName)));
      

      【讨论】:

      • 不错的方式。但是如果我有两个参数来创建一个新的player 怎么办?语法是const playerDetail = [('param1, param2'), ...]吗?
      • 是的,你可以做到[new Player('param1', 'param2')]
      【解决方案3】:

      你可以为玩家创建一个容器类。这将允许容器创建播放器并管理它们。 Players 类可以公开一个接口,从而可以轻松地与玩家单独或作为一个整体进行交互。像这样的东西可能是一个好的开始,并且可以填充更多功能或不同的组织:

      // An individual player. Holds properties and behavior for one player
      class Player {
        constructor(name) {
            this.name = name;
        }
        play() {
          console.log(this.name, "plays")
        }
      }
      
      // Class that holds a collection of players and properties and functions for the group
      class Players {
        constructor(){
          this.players = []
        }
        // create a new player and save it in the collection
        newPlayer(name){
          let p = new Player(name)
          this.players.push(p)
          return p
        }
        get allPlayers(){
          return this.players
        }
        // this could include summary stats like average score, etc. For simplicy, just the count for now
        get numberOfPlayers(){
            return this.players.length
        }
      }
      
      let league = new Players()
      league.newPlayer("Mark")
      league.newPlayer("Roger")
      
      // list all the players
      console.log(league.numberOfPlayers + " Players)
      console.log(league.allPlayers)
      
      
      // make them do something
      league.allPlayers.forEach(player => player.play())

      【讨论】:

      • 你为什么在 newPlayer 上使用 return?
      • 嘿@Shahriar 很好,我想将播放器返回到那里,但返回了push 的结果——我对其进行了编辑以解决该问题。这将让您使用let aPlayer = league.newPlayer("SomePlayer") 并获得对新播放器的引用,这很方便。
      • 现在这很有意义@MarkMeyer :) 我真的很喜欢你解决这个问题的方法(整个问题)。
      • 3年后,我现在明白了JS和你的答案:D标记为接受!
      【解决方案4】:

      我现在无法评论你的答案,所以这里是一个补充:

      class player {
          constructor(name){
              this.name = name;
              PLAYERS.push(this);
          }
      }
      

      请注意:在这几行代码中有很多糟糕的做法,你不应该将构造函数绑定到可能在其他地方初始化也可能不会初始化的变量,用任何外部明显可怕的东西来干预构造函数。此外,类通常是标题大小写的。

      附带说明一下,虽然您可以在保持引用的同时更改 consts 属性是真实的,因此您可以将对象推送到声明为 const 的数组中,但实际上并没有加起来作为自记录代码,所以,如果你要修改这个数组,只需从一开始就用“let”声明它。

      【讨论】:

      • 感谢您的关注。我将 Const 更改为 Let。
      • 你的意思是不要在构造函数中编写多于对象属性的代码?
      • 构造函数应该只与它们在效果上“构造”的东西相关,所以当你绑定一个可能相关或可能不相关的变量时,你基本上放弃了一组功能,比如能够导出这个类没有 PLAYERS 常量。此外,作为良好实践的问题,代码应尽可能声明性(意味着您应该能够在不揭示实现的情况下理解代码在做什么),并且当您实例化一个对象时,您要实例化一个对象,而不是将对象推入一个不相关的数组。所以是的,避免构造函数中不相关的副作用
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-06-29
      • 2021-08-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-26
      相关资源
      最近更新 更多