Eloquent JavaScript - Inheritance (继承)

158 阅读1分钟

继承

Matrix类

class Matrix {
    // 初始化,创建一个matrix[width][height]
    constructor(width, height, element = (x, y) => undefined) {
        this.width = width;
        this.height = height;
        this.content = []; // single array representation of a two-dimensional array

        for (let y = 0; y < height; y++)
            for (let x = 0; x < width; x++)
                this.content[y * width + x] = element(x, y);
    }
    get(x, y) {
        return this.content[y * this.width + x];
    }
    set(x, y, value) {
        this.content[y * this.width + x] = value;
    }
}

SymmetricMatrix(对称矩阵)子类

class SymmetricMatrix extends Matrix {
    constructor(size, element = (x, y) => undefined) {
        super(size, size, (x, y) => {
            if (x < y) return element(y, x);
            else return element(x, y);
        });
    }
    
    set(x, y, value) {
        super.set(x, y, value);
        if (x != y) super.set(y, x, value);
    }
}

MatrixIterator

class MatrixIterator {
    constructor(matrix) {
        this.x = 0;
        this.y = 0;
        this.matrix = matrix;
    }
    // 注意next()的写法
    next() {
        if (this.y == this.matrix.height) return { done: true };
        let value = {
            x: this.x,
            y: this.y,
            value: this.matrix.get(this.x, this.y),
        };
        this.x++;
        if (this.x == this.matrix.width) {
            this.x = 0;
            this.y++;
        }
        return { value, done: false };
    }
}

Matrix.prototype[Symbol.iterator] = function () {
    return new MatrixIterator(this); 
};

分析

  1. Matrix类的constructor,有三个参数:widthheightelement = (x, y) => undefined,也就是矩阵的行数、列数、以及矩阵元素初始设置函数。
  2. SymmetricMatrix的constructor,只需要两个参数:sizeelement = (x, y) => undefined,因为对称矩阵的行数 = 列数,然后在constructor里面,直接使用了super(),super里面有三个参数。最开始直接看代码,其实不知道这个地方到底在做什么,虽然知道肯定有对称的特性有关。创建一个SymmetricMatrix对象,就能更直观地理解这里的代码到底在做什么。
let matrix = new SymmetricMatrix(4, (x, y) => `${x}, ${y}`);
for (let { x, y, value } of matrix) {
    console.log(x, y, value);
}
console.log(matrix.get(2, 3)); // -> "3, 2"