理想情况下,我想做的事情如下:
class Chess = {
constructor() {
this.board = ...;
...
};
class Square = {
constructor(row, col) {
this.row = row;
this.col = col;
};
};
我的主要动机是,与国际象棋和广场类分别定义如下:(指国际象棋课)
this.empty(square)
可以缩短为
square.empty()
其可读性更强且更简洁。
不幸的是我不能
Square.empty()
方法,因为结果取决于Chess类中的信息,并且
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.prototype。例如:
// 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);
};
因此,有时可以使用以下命令创建Square对象
this.createSquare(3, 4);
3条答案
按热度按时间bf1o4zei1#
有人可能会说JavaScript本身没有“嵌套”类--例如,类无法使用父类作用域,除了访问父类属性(
static
元素)之外,它对任何事情都没有意义。JavaScript中的类和其他类一样只是一个对象,所以你也可以定义一个类,然后用另一个类的属性来引用它:
(yes类的名称是可选的--在上面,
Chess
上的Square
属性引用了一个 * 没有名称 * 的类;对于调试和内省来说不一定很好,但只是在这里说明一点)有了上面的内容,你可以做如下事情:
一般来说,你对一个类或一个类的对象所做的一切--
new
只是期望一个函数充当构造函数,而class
声明实际上在程序运行时“衰减”为构造函数--以下所有表达式的值都是true:所以嵌套的 constructors,那么--现在我们已经确定JavaScript类本质上是它的构造函数。好吧,ECMAScript与每个类都有 * 一些 * 额外的元数据,以及 * 一些 * 差异,但它对嵌套构造函数访问外部作用域没有负面影响:
上面使用了所谓的“闭包”,这需要你很好地掌握JavaScript中的 scoping 是如何工作的。在Java中,上面指定的
Square
类被称为嵌套的 instance 类,而不是嵌套的 static 类。答案最上面的第一个例子,使用class
关键字,确实指定了后者的形式,though(一个“静态”类)。下面是另一种定义“示例”类
Square
的方法:JavaScript的特点是,不管是好是坏,它可以以多种方式实现OOP,当然比其他一些“OOP语言”所允许的要多,而且“嵌套类”对不同的人来说可能意味着不同的东西,在不同的项目中。这被称为“有很多绳子可以吊死自己”--有很多工具可以帮助你优雅地实现你想要的模型,和/或使你的代码难以阅读(特别是对那些不像你一样了解JavaScript的人)和调试。这是一个在使用“嵌套类”之前需要解决的权衡。
xzv2uavs2#
目前,有are no nested classes。你可以做的是有两个单独的类,
Chess
和ChessSquare
-并在ChessSquare
的构造函数中传递一个对chess的引用,并将其存储为属性。这样你就不必在ChessSquare
的方法中传递它:您可能希望在
Chess
类本身中创建ChessSquare
的所有示例。3duebb1j3#
下面的代码运行得很好:
这两个独立的类在Chess(main?)类中通过直接调用Square类而相互关联,因此在Chess示例化时,棋盘方格也被定义。