Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
159 views
in Technique[技术] by (71.8m points)

javascript - How to write a proper constructor function extending the Array class

Scenario

I have the following piece of code:

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

I'm instantiating a new Matrix like this:

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

Logging mat to the console gives me as expected,

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

Problem

Now when I call the makeTranspose method of the class, it returns me this:

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

Expected output:

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

What I figured is, the map function calls the constructor of this subclass every time while iterating through the array, which in turn calls super, which then calls the composeMatrix function and a new Matrix gets made.

How can I fix this?

  • I want a class to extend Array with some added methods.
  • The constructor needs to take some relevant parameters and function as expected.
  • I don't want to add functions to the prototype.
question from:https://stackoverflow.com/questions/65906009/how-to-write-a-proper-constructor-function-extending-the-array-class

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

A matrix is not an array. You're better off using 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());

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...