gpt4 book ai didi

javascript - 类中类?

转载 作者:行者123 更新时间:2023-11-29 15:12:15 25 4
gpt4 key购买 nike

理想情况下,我想做如下事情:

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 添加了一个上下文属性

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);
};

所以有时可以创建 Square 对象

this.createSquare(3, 4);

最佳答案

有人可能会争辩说 JavaScript 没有这样的“嵌套”类——例如,类无法使用父类作用域,除了访问父类属性(static 元素)。

JavaScript 中的类就像任何其他对象一样只是一个对象,因此您也可以定义一个对象并使用另一个类的属性来引用它:

class Chess {
}

Chess.Square = class {
};

(是的,类的名称是可选的——在上面,Chess 上的 Square 属性引用了一个没有名称的类;不一定非常适合调试和自省(introspection),只是在这里说明一点)

有了上面的内容,您可以执行以下操作:

new Chess.Square();

通常,您对类或类的对象所做的所有其他事情 -- new 只是期望一个函数充当构造函数,而 class 声明实际上是“程序运行时“衰减”到构造函数中——以下所有表达式的值都为真:

Chess instanceof Function;
typeof Chess == "function";
Chess.Square instanceof Function;
typeof Chess.Square == "function";
Chess.prototype.constructor == Chess;
Chess.Square.prototype.constructor == Chess.Square;

那么嵌套构造函数,那么——既然我们已经确定 JavaScript 类本质上就是它的构造函数。好吧,通过 ECMAScript,每个类都有一些额外的元数据和一些差异,但它对嵌套构造函数以访问外部范围没有负面影响:

function Chess() {
const chess = this;
function Square() { /// Obviously, this function/constructor/class is only available to expressions and statements in the Chess function/constructor/class (and if explicitly "shared" with other code).
Chess; /// Refers to the outer constructor/class -- you can do `new Chess()` etc
this; /// Refers to this Square object being created
chess; /// Refers to what `chess` declared outside this method, refers to at the time of creating this Square object
}
}

上面使用了所谓的“闭包”,这要求您很好地掌握 作用域 在 JavaScript 中的工作原理。在 Java 中,上面指定的 Square 类被称为嵌套的 instance 类,而不是嵌套的 static 类。答案最顶部的第一个示例使用 class 关键字,但确实指定了后者的一种形式(“静态”类)。

这是另一种定义“实例”类 Square 的方法:

class Chess {
constructor() {
this.Square = class {
constructor() {
/// Be vigilant about `this` though -- in every function (except arrow functions) `this` is re-bound, meaning `this` in this constructor refers to an instance of the anonymous class, not to an instance of the `Chess` class; if you want to access the latter instance, you must have a reference to it saved for this constructor to access, e.g. with the `const chess = this;` statement in `Chess` constructor somewhere
}
}; /// Every `Chess` object gets a _distinct_ anonymous class referred to with a property named `Square`; is a class for every object expensive? is it needed? is it useful?
}
}

关于 JavaScript 的事情是,无论好坏,它使得以不止一种方式实现 OOP 成为可能,当然比其他一些“OOP 语言”所允许的方式更多,并且“嵌套类”可以对不同的人和不同的程序意味着不同的事情。这被称为“有很多绳子可以吊死自己”——很多设施可以帮助您优雅地实现您的预​​期模型,和/或使您的代码难以阅读(尤其是对于那些不知道的人和你一样多的 JavaScript)和调试。这是在使用“嵌套类”之前需要解决的权衡问题。

关于javascript - 类中类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53448096/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com