Я пытаюсь преобразовать шаблон проектирования классов 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.info(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.info(x, y, value);
}
Любая подсказка о том, где я, возможно, ошибаюсь, приветствуется.
Изучив код шаблона делегирования в вопросе, я получил больше ясности о концепциях потока шаблона делегирования. Обратитесь к Вы не знаете 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.info(x, y, value);
}
Предлагаемое здесь решение можно улучшить.
@JuanMendes Я цитирую это из [ссылка] (github.com/getify/You-Dont-Know-JS/blob/master/…) «действительно ли в JavaScript есть классы? Просто и понятно: нет. Поскольку классы являются шаблоном проектирования, вы можете, приложив немало усилий, реализовать приближения для большей части классической функциональности классов. . JS пытается удовлетворить чрезвычайно распространенное желание разрабатывать с классами, предоставляя синтаксис, похожий на классовый ".
@JuanMendes В таких языках, как JAVA, экземпляр класса создается в объектной форме с помощью операции копирования. Наследование классов подразумевает копии. JS работает наоборот, он создает связи между объектами. Классы - это простые и простые объекты в JS.
@JuanMendes Чтобы ответить на ваш вопрос, я решил не использовать шаблон проектирования классов (представленный в ECMAScript 2015) в JS.
Неважно, что это не классы как таковые. Он позволяет делать то же самое с более чистым синтаксисом. Я лучше буду прагматиком, чем пуристом. Я считаю этот стиль менее читабельным, чем синтаксис класса.
Почему бы вам просто не сделать
Object.setPrototypeOf
вместоclass MatrixIterator extends Matrix
?