JavaScript-类设计模式为委派设计模式,新构造函数为Object.create()

时间:2018-10-31 12:18:48

标签: javascript

我正在尝试将JavaScript类设计模式转换为委托设计模式。 (您不知道Kyle Simpson的JS系列)

我无法在我的委托设计代码的矩阵对象new Constructor功能中将Object.create()更改为[Symbol.iterator]。我无法为for of循环设置适当的迭代器。

我正在使用Eloquent JavaScript书中第Iterable Interface Section节中的Matrix Iterator代码。您可以在链接中找到正确的代码。

尽管如此,我还是在下面包含了相同的代码。

链接中的

类设计模式代码:

class Matrix {
  constructor(width, height, element = (x, y) => undefined) {
    this.width = width;
    this.height = height;
    this.content = [];

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

class MatrixIterator {
  constructor(matrix) {
    this.x = 0;
    this.y = 0;
    this.matrix = matrix;
  }

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

let matrix = new Matrix(2, 2, (x, y) => `value ${x},${y}`);
for (let {x, y, value} of matrix) {
  console.log(x, y, value);
}
我尝试创建的

委托模式代码

var Matrix = {
  init: function(width, height, element = (x, y) => undefined) {
    this.width = width;
    this.height = height;
    this.content = [];

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

  [Symbol.iterator]: function() {
    var matrixIt = Object.create(MatrixIterator);
    ????????? // **I have no clue what to do here, or even if I am right upto this point**
  },

  get: function(x, y) {
    return this.content[y * this.width + x];
  },

  set: function(x, y, value) {
    this.content[y * this.width + x] = value;
  },
}

var MatrixIterator = Object.create(Matrix);

MatrixIterator = {
  setup: function(matrix) {
    this.x = 0;
    this.y = 0;
    this.matrix = matrix;
  },

  next: function() {
    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};
  }
}

let matrix = Object.create(Matrix);
matrix.init(2, 2, (x, y) => `value ${x},${y}`);
for (let {x, y, value} of matrix) {
  console.log(x, y, value);
}

任何关于我可能出错的线索都受到赞赏。

1 个答案:

答案 0 :(得分:0)

在检查了我的委托模式代码后,我对委托模式流程的概念有了更加清晰的了解。请参阅You Don't Know JS

解决方案:

var Matrix = {
  init: function(width, height, element = (x, y) => undefined) {
    this.width = width;
    this.height = height;
    this.content = [];

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

  get: function(x, y) {
    return this.content[y * this.width + x];
  },

  set: function(x, y, value) {
    this.content[y * this.width + x] = value;
  }
}

var MatrixIterator = {
  setup: function(matrix) {
    this.x = 0;
    this.y = 0;
    this.matrix = matrix;
  },

  [Symbol.iterator]: function() {
    return this;
  },

  next: function() {
    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};
  }
}

Object.setPrototypeOf(MatrixIterator, Matrix);

let matrix = Object.create(Matrix);

matrix.init(2, 2, (x, y) => `value ${x},${y}`);

let matrixIter = Object.create(MatrixIterator);

matrixIter.setup(matrix);

for (let {x, y, value} of matrixIter) {
  console.log(x, y, value);
}

此处提供的解决方案可以进一步改进。