班级内的班级?

时间:2018-11-23 14:01:02

标签: javascript class oop nested

理想情况下,我想执行以下操作:

class Chess = {
  constructor() {
    this.board = ...;
    ...
  };

  class Square = {
    constructor(row, col) {
      this.row = row;
      this.col = col;
  };
};

我的主要动机是在分别定义Chess和Square类的情况下,类似于:(指的是Chess类)

this.empty(square)

可以缩短为

square.empty()

更具可读性和简洁性。

不幸的是,我不能只做一个

Square.empty()

方法,因为结果取决于国际象棋类中的信息,并且

square.empty(chess)

没有真正的进步。

我有一个Square班的原因是类似

square.up()

似乎比类似的东西好

[row, col + 1]

您对我如何实现上述目标有何建议?用某种方法可以在一个类中或完全在其他任何类中编写一个类?

编辑:

按照likle和alex的建议,我做了以下工作:

我在课堂广场上添加了一个上下文属性

class Square = {
  constructor(context, row, col) {
    this.context = context;
    this.row = row;
    this.col = col;
  };
};

然后重新定义一些方法,从Chess.prototype到Square.protoype。例如:

// before
Chess.prototype.empty = function (square) {
  return this.piece(square) === 0;
};

// after
Square.prototype.empty = function () {
  return this.piece() === 0;
};

这意味着每次我创建一个Square对象时,我都需要添加上下文。例如:

new Square(3, 4); // before
new Square(this, 3, 4); // after
new Square(this.context, 3, 4); // sometimes like this

为了使代码更具可读性,我创建了以下方法:

Chess.prototype.createSquare = function (row, col) {
  return new Square(this, row, col);
};

因此有时可以使用创建方形对象

this.createSquare(3, 4);

3 个答案:

答案 0 :(得分:1)

当前,有are no nested classes。您可以做的是拥有两个单独的类ChessChessSquare-并引用在ChessSquare的构造函数中传递的象棋,并将其存储为属性。这样,您就不必在ChessSquare的方法中传递它:

  class ChessSquare = {
    constructor(chess, row, col) {
      this.chess = chess;
      this.row = row;
      this.col = col;
    }

    empty() {
      // "this.chess" references the chess, and "this" references the square.
    }
  };

您可能想在ChessSquare类本身内创建Chess的所有实例。

答案 1 :(得分:0)

有人可能会说JavaScript没有完全嵌套的类-例如,一个类无法使用父类范围,除了父类属性外,它对任何其他事情都没有意义。 (static声明),但是JavaScript中的类与其他任何对象一样,都是对象,因此您最好定义一个并用另一个类的属性引用它:

class Chess {
}

Chess.Square = class {
};

是的,一个类的名称是可选的。

然后您可以执行以下操作:

new Chess.Square();

通常,您对类或类的对象所做的所有其他操作。

答案 2 :(得分:0)

以下代码段运行良好:

class Chess  {
  constructor() {
    this.board = {}
    for (var i=0; i<8; i++) {
          for (var j=0; j<8; j++) {
               this.board[i,j] = new Square(i,j)
               }
          }

  };

};

class Square {
    constructor(row, col) {
      this.row = row;
      this.col = col;
      this.color = "black"
      if ((row+col)%2 == 1) this.color = "white"
  };
};

两个单独的类在Chess(主类)类内相互链接,直接调用Square类,因此在Chess实例化时,还定义了棋盘方块。