KnigaRead.com/
KnigaRead.com » Компьютеры и Интернет » Программирование » Марейн Хавербеке - Выразительный JavaScript

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

На нашем сайте KnigaRead.com Вы можете абсолютно бесплатно читать книгу онлайн Марейн Хавербеке, "Выразительный jаvascript" бесплатно, без регистрации.
Перейти на страницу:

Ага! У двух факторов корреляции заметно больше остальных. Арахис сильно влияет на вероятность превращения в белку, тогда как чистка зубов наоборот, препятствует этому.

Интересно. Попробуем вот что:

for (var i = 0; i < JOURNAL.length; i++) {

  var entry = JOURNAL[i];

  if (hasEvent("арахис", entry) &&

     !hasEvent("чистка зубов", entry))

    entry.events.push("арахис зубы");

}

console.log(phi(tableFor("арахис зубы", JOURNAL)));

// → 1

Ошибки быть не может! Феномен случается именно тогда, когда Жак ест арахис и не чистит зубы. Если б он только не был таким неряхой относительно оральной гигиены, он бы вообще не заметил своего несчастья.

Зная это, Жак просто перестаёт есть арахис и обнаруживает, что трансформации прекратились.

У Жака какое-то время всё хорошо. Но через несколько лет он теряет работу, и в конце концов ему приходится наняться в цирк, где он выступает как Удивительный Человек-белка, набирая полный рот арахисового масла перед шоу. Однажды, устав от столь жалкого существования, Жак не обращается обратно в человека, пробирается через дыру в цирковом тенте и исчезает в лесу. Больше его никто не видел.

Дальнейшая массивология

В конце главы хочу познакомить вас ещё с несколькими концепциями, относящимися к объектам. Начнём с полезных методов, имеющихся у массивов.

Мы видели методы push и pop, которые добавляют и отнимают элементы в конце массива. Соответствующие методы для начала массива называются unshift и shift.

var todoList = [];

function rememberTo(task) {

  todoList.push(task);

}

function whatIsNext() {

  return todoList.shift();

}

function urgentlyRememberTo(task) {

  todoList.unshift(task);

}

Данная программа управляет списком дел. Вы добавляете дела в конец списка, вызывая rememberTo("поесть"), а когда вы готовы заняться чем-то, вызываете whatIsNext(), чтобы получить (и удалить) первый элемент списка. Функция urgentlyRememberTo тоже добавляет задачу, но только в начало списка.

У метода indexOf есть родственник по имени lastIndexOf, который начинает поиск элемента в массиве с конца:

console.log([1, 2, 3, 2, 1].indexOf(2));

// → 1

console.log([1, 2, 3, 2, 1].lastIndexOf(2));

// → 3

Оба метода, indexOf и lastIndexOf, принимают необязательный второй аргумент, который задаёт начальную позицию поиска.

Ещё один важный метод – slice, который принимает номера начального (start) и конечного (end) элементов, и возвращает массив, состоящий только из элементов, попадающих в этот промежуток. Включая тот, что находится по индексу start, но исключая тот, что по индексу end.

console.log([0, 1, 2, 3, 4].slice(2, 4));

// → [2, 3]

console.log([0, 1, 2, 3, 4].slice(2));

// → [2, 3, 4]

Когда индекс end не задан, slice выбирает все элементы после индекса start. У строк есть схожий метод, который работает так же.

Метод concat используется для склейки массивов, примерно как оператор + склеивает строки. В примере показаны методы concat и slice в деле. Функция принимает массив array и индекс index, и возвращает новый массив, который является копией предыдущего, за исключением удалённого элемента, находившегося по индексу index.

function remove(array, index) {

  return array.slice(0, index).concat(array.slice(index + 1));

}

console.log(remove(["a", "b", "c", "d", "e"], 2));

// → ["a", "b", "d", "e"]

Строки и их свойства

Мы можем получать значения свойств строк, например length и toUpperCase. Но попытка добавить новое свойство ни к чему не приведёт:

var myString = "Шарик";

myString.myProperty = "значение";

console.log(myString.myProperty);

// → undefined

Величины типа строка, число и булевские – не объекты, и хотя язык не жалуется на попытки назначить им новые свойства, он на самом деле их не сохраняет. Величины неизменяемы.

Но у них есть свои встроенные свойства. У каждой строки есть набор методов. Самые полезные, пожалуй – slice и indexOf, напоминающие те же методы у массивов.

console.log("кокосы".slice(3, 6));

// → осы

console.log("кокос".indexOf("с"));

// → 4

Разница в том, что у строки метод indexOf может принять строку, содержащую больше одного символа, а у массивов такой метод работает только с одним элементом.

console.log("раз два три".indexOf("ва"));

// → 5

Метод trim удаляет пробелы (а также переводы строк, табуляцию и прочие подобные символы) с обоих концов строки.

console.log("  ладно  n ".trim());

// → ладно

Мы уже сталкивались со свойством строки length. Доступ к отдельным символам строчки можно получить через метод charAt, а также просто через нумерацию позиций, как в массиве:

var string = "abc";

console.log(string.length);

// → 3

console.log(string.charAt(0));

// → a

console.log(string[1]);

// → b

Объект arguments

Когда вызывается функция, к окружению исполняемого тела функции добавляется особая переменная под названием arguments. Она указывает на объект, содержащий все аргументы, переданные функции. Помните, что в JavaScript вы можете передавать функции больше или меньше аргументов, чем объявлено при помощи параметров.

function noArguments() {}

noArguments(1, 2, 3); // Пойдёт

function threeArguments(a, b, c) {}

threeArguments(); // И так можно

У объекта arguments есть свойство length, которое содержит реальное количество переданных функции аргументов. Также у него есть свойства для каждого аргумента под именами 0, 1, 2 и т. д.

Если вам кажется, что это очень похоже на массив – вы правы. Это очень похоже на массив. К сожалению, у этого объекта нет методов типа slice или indexOf, что делает доступ к нему труднее.

function argumentCounter() {

  console.log("Ты дал мне", arguments.length, "аргумента.");

}

argumentCounter("Дядя", "Стёпа", "Милиционер");

// → Ты дал мне 3 аргумента.

Некоторые функции рассчитаны на любое количество аргументов, как console.log. Они обычно проходят циклом по свойствам объекта arguments. Это можно использовать для создания удобных интерфейсов. К примеру, вспомните, как мы создавали записи для журнала Жака:

addEntry(["работа", "тронул дерево", "пицца", "пробежка", "телевизор"], false);

Так как мы часто вызываем эту функцию, мы можем сделать альтернативу, которую проще вызывать:

function addEntry(squirrel) {

  var entry = {events: [], squirrel: squirrel};

  for (var i = 1; i < arguments.length; i++)

    entry.events.push(arguments[i]);

  journal.push(entry);

}

addEntry(true, "работа", "тронул дерево", "пицца", "пробежка", "телевизор");

Эта версия читает первый аргумент как обычно, а по остальным проходит в цикле (начиная с индекса 1, пропуская первый аргумент) и собирает их в массив.

Объект Math

Мы уже видели, что Math – набор инструментов для работы с числами, такими, как Math.max (максимум), Math.min (минимум), и Math.sqrt (квадратный корень).

Объект Math используется просто как контейнер для группировки связанных функций. Есть только один объект Math, и он почти не используется в виде значений. Он просто предоставляет пространство имён для всех этих функций и значений, чтоб не нужно было делать их глобальными.

Слишком большое число глобальных переменных «загрязняет» пространство имён. Чем больше имён занято, тем больше вероятность случайно использовать одно из них в качестве переменной. К примеру, весьма вероятно, что вы захотите использовать имя max для чего-то в своей программе. Поскольку встроенная в JavaScript функция max безопасно упакована в объект Math, нам не нужно волноваться по поводу того, что мы её перезапишем.

Многие языки остановят вас, или хотя бы предупредят, когда вы будете определять переменную с именем, которое уже занято. JavaScript не будет этого делать, поэтому будьте осторожны.

Возвращаясь к объекту Math, если вам нужна тригонометрия, он вам поможет. У него есть cos (косинус), sin (синус), и tan (тангенс), их обратные функции — acos, asin, и atan. Число π (pi) – или, по крайней мере, его близкая аппроксимация, помещающаяся в число JavaScript – также доступно как Math.PI. (Есть такая старая традиция в программировании — записывать имена констант в верхнем регистре.)

function randomPointOnCircle(radius) {

  var angle = Math.random() * 2 * Math.PI;

  return {x: radius * Math.cos(angle),

          y: radius * Math.sin(angle)};

}

console.log(randomPointOnCircle(2));

// → {x: 0.3667, y: 1.966}

Перейти на страницу:
Прокомментировать
Подтвердите что вы не робот:*