【问题标题】:How to write a proper constructor function extending the Array class如何编写扩展 Array 类的正确构造函数
【发布时间】:2021-04-30 12:17:34
【问题描述】:

场景

我有以下代码:

const composeMatrix = (nRow, nCol, filler) => Array(nRow).fill(Array(nCol).fill(filler));

class Matrix extends Array {
    constructor({ nRows = 3, nCols = 3, filler = 0 } = {}) {
        super(...composeMatrix(nRows, nCols, filler));
    }
    makeTranspose() {
        const mat = this;
        const column = mat[0];
        return column.map((_, i) => {
            return mat.map((row) => row[i]);
        });
    }
}

我正在像这样实例化一个新的Matrix

const mat = new Matrix({ nRows: 4, filler: 1 });

mat 记录到控制台给了我预期的结果,

Matrix(4) [ 
  [ 1, 1, 1 ], 
  [ 1, 1, 1 ], 
  [ 1, 1, 1 ],
  [ 1, 1, 1 ]
]

问题

现在,当我调用该类的 makeTranspose 方法时,它会返回:

[ 
  Matrix(4) [ 1, 1, 1, 1 ], 
  Matrix(4) [ 1, 1, 1, 1 ],
  Matrix(4) [ 1, 1, 1, 1 ] 
]

预期输出:

Matrix(3) [
  [ 1, 1, 1, 1 ], 
  [ 1, 1, 1, 1 ], 
  [ 1, 1, 1, 1 ]
]

我的想法是,map函数每次遍历数组时都会调用这个子类的构造函数,然后调用super,然后调用composeMatrix函数并生成一个新的矩阵。

我该如何解决这个问题?

  • 我想要一个 class 来扩展 Array 并添加一些方法。
  • 构造函数需要按预期获取一些相关参数和函数。
  • 我不想向prototype 添加函数。

【问题讨论】:

标签: javascript arrays class oop constructor


【解决方案1】:

矩阵不是数组。你最好使用composition over inheritance

Array.create = (length, mapping) =>
    Array.from({ length }, (value, index) => mapping(index));

class Matrix {
    constructor(rows, cols, data) {
        this.rows = rows;
        this.cols = cols;
        this.data = data;
    }

    static create(rows, cols, mapping) {
        const data = Array.create(rows, row =>
            Array.create(cols, col => mapping(row, col)));
        return new Matrix(rows, cols, data);
    }

    transpose() {
        const { rows, cols, data } = this;
        return Matrix.create(cols, rows, (row, col) => data[col][row]);
    }
}

const mat = Matrix.create(4, 3, (row, col) => 1);

console.log(mat.transpose());

使用函数式编程风格。

const array = (length, mapping) =>
    Array.from({ length }, (value, index) => mapping(index));

const Matrix = (rows, cols, data) => ({ rows, cols, data });

const matrix = (rows, cols, mapping) =>
    Matrix(rows, cols, array(rows, row =>
        array(cols, col => mapping(row, col))));

const transpose = ({ rows, cols, data }) =>
    matrix(cols, rows, (row, col) => data[col][row]);

const mat = matrix(4, 3, (row, col) => 1);

console.log(transpose(mat));

【讨论】:

  • 我最终按照这些思路做了一些事情。 Implementation。谢谢你的回答。
猜你喜欢
  • 2020-07-20
  • 1970-01-01
  • 2013-01-30
  • 1970-01-01
  • 2014-12-29
  • 1970-01-01
  • 2020-08-20
  • 2018-09-26
  • 2013-05-29
相关资源
最近更新 更多