[] 覆盖 class 访问权限
Overriding class access by []
如果我有自己的自定义矩阵 class,我如何通过括号定义对它的访问?比如我怎样才能实现:
const matrix = new Matrix(2,2)
matrix[0, 0] = 1
matrix[0, 1] = 2
matrix[1, 0] = 3
matrix[1, 1] = 4
console.log(matrix[1, 1]) // prints 4.
// or...
matrix[0][0] = 1
matrix[0][1] = 2
matrix[1][0] = 3
matrix[1][1] = 4
console.log(matrix[1][1]) // prints 4.
,假设 new Matrix(2,2) 包含一个二维未初始化数组。
...how can I define access to it by brackets
你不能,以你所展示的方式。 JavaScript 没有相应的语法;相反,它有逗号运算符,它不会做你想要的。 0, 1
和 1, 1
都计算为 1
因为逗号运算符接受两个操作数,计算 left-hand 操作数,丢弃该值,然后计算 right-hand 操作数并将该结果作为逗号运算符的结果。所以 matrix[0, 1]
是 matrix[1]
.
相反,定义一个接受两个参数的方法,并调用它 (matrix.at(0, 1)
),或者使用数组数组并执行 matrix[0][1]
.
你 可以 通过使用 Proxy
object and then parsing the string in the get
and set
陷阱接受字符串 matrix["0,1"]
,但我怀疑这不适合你的用例(或大多数其他)。
你说过矩阵的宽高是在构造函数中设置的。您可以将您的字段存储在数组中(可能是类型化数组的数组,具体取决于您在矩阵中存储的内容)并为 0
到 height - 1
定义属性以获取该行的数组。所以 matrix[0]
将是矩阵的第一行作为数组/类型数组,所以 matrix[0][0]
将是第一行的第一个单元格。这是一个非常基本的例子:
class Matrix {
constructor(height, width) {
this.data = Array.from(
{length: height},
() => Array.from({length: width}).fill(0)
);
for (let y = 0; y < height; ++y) {
Object.defineProperty(this, y, {
value: this.data[y]
});
}
}
toString() {
return this.data.map(row => row.join(",")).join("\n");
}
}
const m = new Matrix(5, 5);
m[1][2] = 1;
console.log(m.toString());
我在那里使用了 defineProperty
,因为我认为我们不希望任何人写信给这些。通过不提供任何标志(writable
、configurable
、enumerable
),我们采用所有默认值,即 false
.
或者(比如)每行一个 Uint8Array
:
class Matrix {
constructor(height, width) {
this.data = Array.from(
{length: height},
() => Uint8Array.from({length: width}).fill(0)
// Only change is ^^^^^^^^^^
);
for (let y = 0; y < height; ++y) {
Object.defineProperty(this, y, {
value: this.data[y]
});
}
}
toString() {
return this.data.map(row => row.join(",")).join("\n");
}
}
const m = new Matrix(5, 5);
m[1][2] = 1;
console.log(m.toString());
如果我有自己的自定义矩阵 class,我如何通过括号定义对它的访问?比如我怎样才能实现:
const matrix = new Matrix(2,2)
matrix[0, 0] = 1
matrix[0, 1] = 2
matrix[1, 0] = 3
matrix[1, 1] = 4
console.log(matrix[1, 1]) // prints 4.
// or...
matrix[0][0] = 1
matrix[0][1] = 2
matrix[1][0] = 3
matrix[1][1] = 4
console.log(matrix[1][1]) // prints 4.
,假设 new Matrix(2,2) 包含一个二维未初始化数组。
...how can I define access to it by brackets
你不能,以你所展示的方式。 JavaScript 没有相应的语法;相反,它有逗号运算符,它不会做你想要的。 0, 1
和 1, 1
都计算为 1
因为逗号运算符接受两个操作数,计算 left-hand 操作数,丢弃该值,然后计算 right-hand 操作数并将该结果作为逗号运算符的结果。所以 matrix[0, 1]
是 matrix[1]
.
相反,定义一个接受两个参数的方法,并调用它 (matrix.at(0, 1)
),或者使用数组数组并执行 matrix[0][1]
.
你 可以 通过使用 Proxy
object and then parsing the string in the get
and set
陷阱接受字符串 matrix["0,1"]
,但我怀疑这不适合你的用例(或大多数其他)。
你说过矩阵的宽高是在构造函数中设置的。您可以将您的字段存储在数组中(可能是类型化数组的数组,具体取决于您在矩阵中存储的内容)并为 0
到 height - 1
定义属性以获取该行的数组。所以 matrix[0]
将是矩阵的第一行作为数组/类型数组,所以 matrix[0][0]
将是第一行的第一个单元格。这是一个非常基本的例子:
class Matrix {
constructor(height, width) {
this.data = Array.from(
{length: height},
() => Array.from({length: width}).fill(0)
);
for (let y = 0; y < height; ++y) {
Object.defineProperty(this, y, {
value: this.data[y]
});
}
}
toString() {
return this.data.map(row => row.join(",")).join("\n");
}
}
const m = new Matrix(5, 5);
m[1][2] = 1;
console.log(m.toString());
我在那里使用了 defineProperty
,因为我认为我们不希望任何人写信给这些。通过不提供任何标志(writable
、configurable
、enumerable
),我们采用所有默认值,即 false
.
或者(比如)每行一个 Uint8Array
:
class Matrix {
constructor(height, width) {
this.data = Array.from(
{length: height},
() => Uint8Array.from({length: width}).fill(0)
// Only change is ^^^^^^^^^^
);
for (let y = 0; y < height; ++y) {
Object.defineProperty(this, y, {
value: this.data[y]
});
}
}
toString() {
return this.data.map(row => row.join(",")).join("\n");
}
}
const m = new Matrix(5, 5);
m[1][2] = 1;
console.log(m.toString());