Марейн Хавербеке - Выразительный JavaScript

Тут можно читать онлайн Марейн Хавербеке - Выразительный JavaScript - бесплатно полную версию книги (целиком) без сокращений. Жанр: comp-programming. Здесь Вы можете читать полную версию (весь текст) онлайн без регистрации и SMS на сайте лучшей интернет библиотеки ЛибКинг или прочесть краткое содержание (суть), предисловие и аннотацию. Так же сможете купить и скачать торрент в электронном формате fb2, найти и слушать аудиокнигу на русском языке или узнать сколько частей в серии и всего страниц в публикации. Читателям доступно смотреть обложку, картинки, описание и отзывы (комментарии) о произведении.

Марейн Хавербеке - Выразительный JavaScript краткое содержание

Выразительный JavaScript - описание и краткое содержание, автор Марейн Хавербеке, читайте бесплатно онлайн на сайте электронной библиотеки LibKing.Ru

В процессе чтения вы познакомитесь с основами программирования и, в частности, языка JavaScript, а также выполните несколько небольших проектов. Один из самых интересных проектов — создание своего языка программирования.

Выразительный JavaScript - читать онлайн бесплатно полную версию (весь текст целиком)

Выразительный JavaScript - читать книгу онлайн бесплатно, автор Марейн Хавербеке
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

Конструкция || "s"в методе actнужна, чтобы this.directionне получил null, в случае если существо забилось в угол без свободного пространства вокруг – например, окружено другими существами.

Мировой объект

Теперь можно приступать к мировому объекту World. Конструктор принимает план (массив строк, представляющих сетку мира) и объект legend. Это объект, сообщающий, что означает каждый из символов карты. В нём есть конструктор для каждого символа – кроме пробела, который ссылается на null(представляющий пустое пространство).

function elementFromChar(legend, ch) {

if (ch == " ")

return null;

var element = new legend[ch]();

element.originChar = ch;

return element;

}

function World(map, legend) {

var grid = new Grid(map[0].length, map.length);

this.grid = grid;

this.legend = legend;

map.forEach(function(line, y) {

for (var x = 0; x < line.length; x++)

grid.set(new Vector(x, y),

elementFromChar(legend, line[x]));

});

}

В elementFromCharмы сначала создаём экземпляр нужного типа, находя конструктор символа и применяя к нему new. Потом добавляем свойство originChar, чтобы было просто выяснить, из какого символа элемент был создан изначально.

Нам понадобится это свойство originCharпри изготовлении мирового метода toString. Метод строит карту в виде строки из текущего состояния мира, проходя двумерным циклом по клеткам сетки.

function charFromElement(element) {

if (element == null)

return " ";

else

return element.originChar;

}

World.prototype.toString = function() {

var output = "";

for (var y = 0; y < this.grid.height; y++) {

for (var x = 0; x < this.grid.width; x++) {

var element = this.grid.get(new Vector(x, y));

output += charFromElement(element);

}

output += "\n";

}

return output;

};

Стена wall– простой объект. Используется для занятия места и не имеет метода act.

function Wall() {}

Проверяя объект World, создав экземпляр с использованием плана, заданного в начале главы, и затем вызвав его метод toString, мы получим очень похожую на этот план строку.

var world = new World(plan, {"#": Wall, "o": BouncingCritter});

console.log(world.toString());

// → ############################

// # # # o ##

// # #

// # ##### #

// ## # # ## #

// ### ## # #

// # ### # #

// # #### #

// # ## o #

// # o # o ### #

// # # #

// ############################

this и его область видимости

В конструкторе Worldесть вызов forEach. Хочу отметить, что внутри функции, передаваемой в forEach, мы уже не находимся непосредственно в области видимости конструктора. Каждый вызов функции получает своё пространство имён, поэтому thisвнутри неё уже не ссылается на создаваемый объект, на который ссылается thisснаружи функции. И вообще, если функция вызывается не как метод, thisбудет относиться к глобальному объекту.

Значит, мы не можем писать this.gridдля доступа к сетке изнутри цикла. Вместо этого внешняя функция создаёт локальную переменную grid, через которую внутренняя функция получает доступ к сетке.

Это промах в дизайне JavaScript. К счастью, в следующей версии есть решение этой проблемы. А пока есть пути обхода. Обычно пишут var self = thisи после этого работают с переменной self.

Другое решение – использовать метод bind, который позволяет привязаться к конкретному объекту this.

var test = {

prop: 10,

addPropTo: function(array) {

return array.map(function(elt) {

return this.prop + elt;

}.bind(this));

}

};

console.log(test.addPropTo([5]));

// → [15]

Функция, передаваемая в map– результат привязки вызова, и посему её thisпривязан к первому аргументу, переданному в bind, то есть переменной thisвнешней функции (в которой содержится объект test).

Большинство стандартных методов высшего порядка у массивов, таких как forEachи map, принимают необязательный второй аргумент, который тоже можно использовать для передачи thisпри вызовах итерационной функции. Вы могли бы написать предыдущий пример чуть проще:

var test = {

prop: 10,

addPropTo: function(array) {

return array.map(function(elt) {

return this.prop + elt;

}, this); // ← без bind

}

};

console.log(test.addPropTo([5]));

// → [15]

Это работает только с теми функциями высшего порядка, у которых есть такой контекстный параметр. Если нет – приходится использовать другие упомянутые подходы.

В нашей собственной функции высшего порядка мы можем включить поддержку контекстного параметра, используя метод callдля вызова функции, переданной в качестве аргумента. К примеру, вот вам метод forEachдля нашего типа Grid, вызывающий заданную функцию для каждого элемента сетки, который не равен nullили undefined:

Grid.prototype.forEach = function(f, context) {

for (var y = 0; y < this.height; y++) {

for (var x = 0; x < this.width; x++) {

var value = this.space[x + y * this.width];

if (value != null)

f.call(context, value, new Vector(x, y));

}

}

};

Оживляем мир

Следующий шаг – создание метода turn(ход) для мирового объекта, дающего существам возможность действовать. Он будет обходить сетку методом forEach, и искать объекты, у которых есть метод act. Найдя объект, turnвызывает этот метод, получая объект actionи производит это действие, если оно допустимо. Пока мы понимаем только действие “move”.

Есть одна возможная проблема. Догадаетесь, какая? Если мы позволим существам двигаться по мере того, как мы их перебираем, они могут перейти на клетку, которую мы ещё не обработали, и тогда мы позволим им сдвинуться ещё раз, когда очередь дойдёт до этой клетки. Таким образом, нам надо хранить массив существ, которые уже сделали свой шаг, и игнорировать их при повторном проходе.

World.prototype.turn = function() {

var acted = [];

this.grid.forEach(function(critter, vector) {

if (critter.act && acted.indexOf(critter) == -1) {

acted.push(critter);

this.letAct(critter, vector);

}

}, this);

};

Второй параметр метода forEachиспользуется для доступа к правильной переменной thisво внутренней функции. Метод letActсодержит логику, которая позволяет существам двигаться.

World.prototype.letAct = function(critter, vector) {

var action = critter.act(new View(this, vector));

if (action && action.type == "move") {

var dest = this.checkDestination(action, vector);

if (dest && this.grid.get(dest) == null) {

this.grid.set(vector, null);

this.grid.set(dest, critter);

}

}

};

World.prototype.checkDestination = function(action, vector) {

if (directions.hasOwnProperty(action.direction)) {

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать


Марейн Хавербеке читать все книги автора по порядку

Марейн Хавербеке - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки LibKing.




Выразительный JavaScript отзывы


Отзывы читателей о книге Выразительный JavaScript, автор: Марейн Хавербеке. Читайте комментарии и мнения людей о произведении.


Понравилась книга? Поделитесь впечатлениями - оставьте Ваш отзыв или расскажите друзьям

Напишите свой комментарий
x