Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Язык JavaScript часть1.pdf
Скачиваний:
204
Добавлен:
22.03.2016
Размер:
8.92 Mб
Скачать

Например:

truncate("Вот, что мне хотелось бы сказать на эту тему:", 20) = "Вот, что мне хоте..."

truncate("Всем привет!", 20) = "Всем привет!"

Эта функция имеет применение в жизни. Она используется, чтобы усекать слишком длинные темы сообщений.

Открыть песочницу с тестами для задачи.

К решению

Выделить число

важность: 4

Есть стоимость в виде строки: "$120". То есть, первым идёт знак валюты, а затем — число.

Создайте функцию extractCurrencyValue(str), которая будет из такой строки выделять числозначение, в данном случае 120.

Открыть песочницу с тестами для задачи.

К решению

Объекты как ассоциативные массивы

Объекты в JavaScript сочетают в себе два важных функционала.

Первый — это ассоциативный массив: структура, пригодная для хранения любых данных. В этой главе мы рассмотрим использование объектов именно как массивов.

Второй — языковые возможности для объектно-ориентированного программирования. Эти возможности мы изучим в последующих разделах учебника.

Ассоциативные массивы

Ассоциативный массив — структура данных, в которой можно хранить любые данные в формате ключ-значение.

Её можно легко представить как шкаф с подписанными ящиками. Все данные хранятся в ящичках. По имени можно легко найти ящик и взять то значение, которое в нём лежит.

В отличие от реальных шкафов, в ассоциативный массив можно в любой момент добавить новые именованные «ящики» или удалить существующие. Далее мы увидим примеры, как это делается.

Кстати, в других языках программирования такую структуру данных также называют «словарь» и «хэш».

Создание объектов

Пустой объект («пустой шкаф») может быть создан одним из двух синтаксисов:

1. o = new Object();

2. o = {}; // пустые фигурные скобки

Обычно все пользуются синтаксисом (2), т.к. он короче.

Операции с объектом

Объект может содержать в себе любые значения, которые называются свойствами объекта. Доступ к свойствам осуществляется по имени свойства (иногда говорят «по ключу»).

Например, создадим объект personдля хранения информации о человеке:

var person = {}; // пока пустой

Основные операции с объектами — это создание, получение и удаление свойств.

Для обращения к свойствам используется запись «через точку», вида объект.свойство, например:

// при присвоении свойства в объекте автоматически создаётся "ящик" // с именем "name" и в него записывается содержимое 'Вася' person.name = 'Вася';

person.age = 25; // запишем ещё одно свойство: с именем 'age' и значением 25

Значения хранятся «внутри» ящиков. Обратим внимание — любые значения, любых типов: число, строка — не важно.

Чтобы прочитать их — также обратимся через точку:

alert( person.name + ': ' + person.age ); // "Вася: 25"

Удаление осуществляется оператором delete:

delete person.age;

Осталось только свойство name:

Следующая операция:

4. Проверка существования свойства с определенным ключом.

Для проверки существования свойства в объекте есть оператор in.

Его синтаксис: "prop" in obj, причем имя свойства — в виде строки, например:

if ("name" in person) {

alert( "Свойство name существует!" );

}

Впрочем, чаще используется другой способ — сравнение значения с undefined.

Дело в том, что в JavaScript можно обратиться к любому свойству объекта, даже если его нет.

Ошибки не будет.

Но если свойство не существует, то вернется специальное значение undefined:

var person = {};

alert( person.lalala ); // undefined, нет свойства с ключом lalala

Таким образом мы можем легко проверить существование свойства — получив его и сравнив с undefined:

var person = { name: "Василий"

};

alert( person.lalala === undefined ); // true, свойства нет alert( person.name === undefined ); // false, свойство есть.

Разница между проверками inи === undefined

Есть два средства для проверки наличия свойства в объекте: первое — оператор in, второе — получить его и сравнить его с undefined.

Они почти идентичны, но есть одна небольшая разница.

Дело в том, что технически возможно, что свойство есть и равно undefined:

var obj = {};

obj.test = undefined; // добавили свойство со значением undefined

// проверим наличие свойств test и заведомо отсутствующего blabla alert( obj.test === undefined ); // true

alert( obj.blabla === undefined ); // true

…При этом, как видно из кода, при простом сравнении наличие такого свойства будет неотличимо от его отсутствия.

Но оператор inгарантирует правильный результат:

var obj = {}; obj.test = undefined;

alert( "test" in obj ); // true alert( "blabla" in obj ); // false

Как правило, в коде мы не будем присваивать undefined, чтобы корректно работали обе

проверки. А в качестве значения, обозначающего неизвестность и неопределенность, будем использовать null.

Доступ через квадратные скобки

Существует альтернативный синтаксис работы со свойствами, использующий квадратные скобки

объект['свойство']:

var person = {};

person['name'] = 'Вася'; // то же что и person.name = 'Вася'

Записи person['name']и person.nameидентичны, но квадратные скобки позволяют использовать в качестве имени свойства любую строку:

var person = {};

person['любимый стиль музыки'] = 'Джаз'; // то же что и person.name = 'Вася'

Такое присвоение было бы невозможно «через точку», так интерпретатор после первого пробела

подумает, что свойство закончилось, и далее выдаст ошибку:

person.любимый стиль музыки = 'Джаз'; // ??? ошибка

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

— JavaScript приведет его к строке автоматически.

Доступ к свойству через переменную

Квадратные скобки также позволяют обратиться к свойству, имя которого хранится в переменной:

var person = { age: 25

};

var key = 'age';

alert( person[key] ); // выведет person['age']

Вообще, если имя свойства хранится в переменной (var key = "age"), то единственный способ к нему обратиться — это квадратные скобки person[key].

Доступ через точку используется, если мы на этапе написания программы уже знаем название свойства. А если оно будет определено по ходу выполнения, например, введено посетителем и записано в переменную, то единственный выбор — квадратные скобки.

Объявление со свойствами

Объект можно заполнить значениями при создании, указав их в фигурных скобках: { ключ1:

значение1, ключ2: значение2, ... }.

Такой синтаксис называется литеральным (англ. literal).

Следующие два фрагмента кода создают одинаковый объект:

var menuSetup = { width: 300, height: 200, title: "Menu"

};

// то же самое, что:

var menuSetup = {}; menuSetup.width = 300; menuSetup.height = 200; menuSetup.title = 'Menu';

Названия свойств можно перечислять как в кавычках, так и без, если они удовлетворяют ограничениям для имён переменных.

Например:

var menuSetup = { width: 300, 'height': 200,

"мама мыла раму": true };

В качестве значения можно тут же указать и другой объект:

var user = { name: "Таня", age: 25, size: {

top: 90, middle: 60, bottom: 90

}

}

alert(user.name) // "Таня"

alert(user.size.top) // 90

Здесь значением свойства sizeявляется объект {top: 90, middle: 60, bottom: 90 }.

Компактное представление объектов

Hardcore coders only

Эта секция относится ко внутреннему устройству структуры данных. Она не обязательна к прочтению.

Браузер использует специальное «компактное» представление объектов, чтобы сэкономить память в том случае, когда однотипных объектов много.

Например, посмотрим на такой объект:

var user = { name: "Vasya", age: 25

};

Здесь содержится информация о свойстве nameи его строковом значении, а также о свойстве ageи его численном значении. Представим, что таких объектов много.

Получится, что информация об именах свойств nameи ageдублируется в каждом объекте. Чтобы этого избежать, браузер применяет оптимизацию.

При создании множества объектов одного и того же вида (с одинаковыми полями) интерпретатор выносит описание полей в отдельную структуру. А сам объект остаётся в виде непрерывной области памяти с данными.

Например, есть много объектов с полями nameи age:

{name: "Вася", age: 25} {name: "Петя", age: 22} {name: "Маша", age: 19}

...

Для их эффективного хранения будет создана структура, которая описывает данный вид объектов. Выглядеть она будет примерно так: <string name, number age>. А сами объекты будут представлены

в памяти только данными:

<структура: string name, number age>

Вася 25 Петя 22 Маша 19

При добавлении нового объекта такой структуры достаточно хранить значения полей, но не их имена. Экономия памяти — налицо.

А что происходит, если к объекту добавляется новое свойство? Например, к одному из них добавили свойство isAdmin:

user.isAdmin = true;

В этом случае браузер смотрит, есть ли уже структура, под которую подходит такой объект. Если нет

— она создаётся и объект привязывается к ней.

Эта оптимизация является примером того, что далеко не всё то, что мы пишем, один-в-один переносится в память.

Современные интерпретаторы очень стараются оптимизировать как код, так и структуры данных. Детали применения и реализации этого способа хранения варьируются от браузера к браузеру. О том, как это сделано в Chrome можно узнать, например, из презентации Know Your Engines . Она была некоторое время назад, но с тех пор мало что изменилось.

Итого

Объекты — это ассоциативные массивы с дополнительными возможностями:

Доступ к элементам осуществляется:

Напрямую по ключу obj.prop = 5

Через переменную, в которой хранится ключ:

var key = "prop"; obj[key] = 5

Удаление ключей: delete obj.name.

Существование свойства может проверять оператор in: if ("prop" in obj), как правило, работает и просто сравнение if (obj.prop !== undefined).