> 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) {