Javascript - - шаблон проектирования класса для шаблона проектирования делегирования, новый конструктор в object.create ()

Я пытаюсь преобразовать шаблон проектирования классов JavaScript в шаблон проектирования делегирования. (Вы не знаете серию JS от Кайла Симпсона)

Я не могу изменить new Constructor на Object.create() в функции [Symbol.iterator]Матричный объект моего кода дизайна делегирования. Я не могу настроить правильный итератор для цикла for of.

Я работаю с кодом Matrix Iterator в книге Eloquent JavaScript, раздел: Итерируемый раздел интерфейса. Вы можете найти правильный код по ссылке.

Тем не менее, я включил тот же код ниже.

Шаблон дизайна класса Код как по ссылке:

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

Любая подсказка о том, где я, возможно, ошибаюсь, приветствуется.

0
0
200
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Изучив код шаблона делегирования в вопросе, я получил больше ясности о концепциях потока шаблона делегирования. Обратитесь к Вы не знаете 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);
}

Предлагаемое здесь решение можно улучшить.

Почему бы вам просто не сделать Object.setPrototypeOf вместо class MatrixIterator extends Matrix?

Juan Mendes 03.11.2018 13:17

@JuanMendes Я цитирую это из [ссылка] (github.com/getify/You-Dont-Know-JS/blob/master/…) «действительно ли в JavaScript есть классы? Просто и понятно: нет. Поскольку классы являются шаблоном проектирования, вы можете, приложив немало усилий, реализовать приближения для большей части классической функциональности классов. . JS пытается удовлетворить чрезвычайно распространенное желание разрабатывать с классами, предоставляя синтаксис, похожий на классовый ".

HarshvardhanSharma 04.11.2018 17:19

@JuanMendes В таких языках, как JAVA, экземпляр класса создается в объектной форме с помощью операции копирования. Наследование классов подразумевает копии. JS работает наоборот, он создает связи между объектами. Классы - это простые и простые объекты в JS.

HarshvardhanSharma 04.11.2018 17:24

@JuanMendes Чтобы ответить на ваш вопрос, я решил не использовать шаблон проектирования классов (представленный в ECMAScript 2015) в JS.

HarshvardhanSharma 04.11.2018 17:29

Неважно, что это не классы как таковые. Он позволяет делать то же самое с более чистым синтаксисом. Я лучше буду прагматиком, чем пуристом. Я считаю этот стиль менее читабельным, чем синтаксис класса.

Juan Mendes 05.11.2018 14:47

Другие вопросы по теме