Шаблон раннего возврата (return early pattern) в JavaScript - это простой способ уменьшить число else-операторов в теле функции до нуля. Есть много причин, чтобы предпочесть этот шаблон использованию else-операторов.
Уменьшение общего количества кода на странице
Уменьшение длины строк кода упрощением логической сложности
Улучшение удобочитаемости кода
Суть шаблона раннего возврата (return early pattern) заключается в том, чтобы заменить необходимость дополнительных условий в функциях JavaScript, используя ключевое слово return в теле оператора if.
Создадим функцию, которая ведет себя по-разному при определенных условиях (примечание: это тривиальный и надуманный пример, просто чтобы получить представление о сути вопроса):
Хотя данная функция кажется читаемой, добавим в нее еще одно условие для проверки того, что функция вызывается для работы с объектом вместо undefined:
Эта функция понятной и ее имя является описательным, однако она представляется все-же излишне сложной. Можем ли мы использовать шаблон раннего возврата (return early pattern) для повышения удобочитаемости и уменьшения количества else-выражений?
Попробуем:
Используя шаблон раннего возврата (return early pattern), мы смогли удалить все ненужные else-инструкции и сделать функцию намного яснее и более краткой.
Бонус: одно условное выражение
Мы можем дополнительно переписать функцию для использования только одного оператора if.
Метод call и apply достаточно древние - они оба из стандарта ES3. Суть создания и работы методов - заставить некоторую произвольную функцию работать на каком-то объекте. Точнее - использовать контекст этого объекта.
Чтобы было понятнее, начнем с примера. Есть функция, которая работает таким образом:
Что будет, если вызвать эту функцию таким образом?
Сложный вопрос, так как мы видим, что в теле функции используется ключевое слово this. Это - ссылка на текущий объект и на свойство name этого объекта. Что это за объект? Неизвестно. Все будет зависеть от того, где будет вызвана функция getName() на исполнение. Допустим, если вызвать функцию в консоли браузера, то парсер обратиться к глобальному объекту window и попробует найти у него свойство name. В итоге мы получим undefined, так как вряд ли у объекта window есть свойство name.
При помощи метода call можно “привязать” функцию getName() к любому объекту. Другими словами - привязать контекст функции getName() к контексту объекта. Как?
Допустим, у нас есть объект:
Мы сделаем так:
Что будет происходить здесь? В этом случае ключевое слово this (в теле функции getName) будет указывать на объект user1, у которого есть свойство name. Как результат - в константе result1 будет находиться значение Ivan.
Если создадим еще один объект:
И на нем вызовем функцию getName():
Что будет? В этом случае функция getName будет ссылаться уже на объект user2! И в константе result2 уже будет значение свойства name объекта user2 - Joshua.
call - более сложный вариант
Рассмотрим более сложный случай - когда функция принимает аргумент(ы). Допустим, такая функция,
И есть два объекта:
Вызовем функцию promote() на каждом из объектов:
Что здесь произойдет? При каждом вызове функции promote() у нее будет разный контекст выполнения - объект junior, middle или senior. И обращаться функция promote() будет каждый раз к свойствам разных объектов - junior, middle или senior. Соответственно, результат тоже будет разным:
Метод apply
Метод apply очень похож на метод call, за одним исключением. Аргументы метод apply принимает в виде массива, а не в виде списка, как метод call.
Проиллюстрируем пример - переделаем вызов функции promote() при помощи метода apply:
Видим, что аргументы передаются в виде массива, но результат будет тот же. Как часто упоминается в различных туториалах, это сделано для того, чтобы передать неограниченное и заранее неизвестное количество аргументов.
Метод bind
Этот метод похож на предыдущие два - call и apply. Однако, у него есть два отличия - этот метод появился в стандарте ES5; и второе отличие - этот метод позволяет выполнить отложенный вызов функции.
То есть - метод call или apply вызываются на исполнение сразу, и результат их работы мы получаем сразу. С методом bind немного иначе:
Что мы сдесь сделали? Мы вызвали функции promote() и передали ей контекст выполнения; результат - экземпляр функции promote() с уже встроенным контекстом выполнения; экземпляр помещен в константу resultAA, resultBB или resultCC. Другими словами - это готовые функции с контекстом.
Осталось вызвать любую из них и передать ей аргументы, которые она ожидает:
Получим результат:
Видим - мы получили отложенный вызов каждой из функций.
Приступили к самому основному - операциям создания, чтения, изменения и удаления документов в MongoDB.
Аббревиатура для этих четырех операций - CRUD ( Create, Read, Update, Delete ).
В этом обзоре будет рассмотрен процесс создания документа - Create.
Два основных метода для создания нового документа в коллекции - метод insert и метод save.
Метод insert()
Команда создания нового документа в коллекции выглядит так:
COLLECTION_NAME - это имя коллекции, в которой будет создаваться новый документ. document - это JavaScript-объект.
Создам новый документ в коллекции customers базы данных users. Для этого перейду в эту базу данных:
Создам коллецию customers в базе данных users:
Создам в коллекции customers новый документ. Можно использовать как одинарные, так и двойные кавычки - дело вкуса:
MongoDB выдает отчет о выполнении команды в строке:
Видно, что операция WriteResult успешно выполнилась - nInserted в значении true.
Как хорошо видно, создаваемый документ - это объект. Если нужно создать сразу несколько документов, то методу insert передается массив этих объектов:
BulkWriteResult выдает подробную информацию о выполненных операциях. Видно, что была выполнена только операция создания документа - “nInserted” : 2.
Просмотр списка документов
Вывести список созданных документов в коллекции customers можно при помощи метода .find():
Видно, что у каждого созданного мною документа есть ключ _id со значением ObjectId(). Этого ключа я не указывал при создании документа.
Все правильно - этот ключ и его значение MongoDB генерирует автоматически и присваивает каждому создаваемому документу. Таким образом MongoDB делает все документы уникальными - нет ни одного документа с одинаковым _id.
Можно сделать вывод метода .find() более читабельным, если подключить к нему по цепочке еще один метод - .pretty():
Метод save()
С помощью метода save() также можно создавать новый документ в коллекции. Создам еще один документ:
Сообщение от MongoDB говорит мне, что операция была выполнена успешно. Посмотрю на результат:
Отличие метода save() от метода insert() заключается в том, что если при создании документа будет передан ключ _id уже существующего документа, то существующий документ будет перезаписан новым.
Вот у меня создан документ:
И он успешно добавлен в коллекцию customers с уникальным ключом “_id” : ObjectId(“5920166b986c86064996f59e”):
Теперь я создаю новый документ, но передаю в него существующую пару ключ-значение “_id” : ObjectId(“5920166b986c86064996f59e”):
Смотрю результат:
… и вижу, что последний документ был полностью перезаписан. Вуаля.
Понятие документа - основа MongoDB. Недаром говорится, что MongoDB - документо-ориентированная система управления базами данных.
Document входит в состав collection и наполняет ее содержимым. Document - это обычный JSON-объект.
Если есть навык создания и работы с JSON-объектами, то уже можно создавать документы в MongoDB.
Простой пример документа в базе данных MongoDB:
Стоит обратить внимание на ключ “_id” - этот ключ и значение ключа MongoDB автоматически генерирует для уникальной идентификации каждого документа в базе данных.
Чуть более сложный пример документа в MongoDB:
В данном случае документ состоит из нескольких типов данных - Number, Array, String, Boolean.
Два документа в коллекции canada базы данных users:
Таких документов в коллекции canada может быть сколько угодно.
Вот в принципе и все, что нужно знать о документах в MongoDB.
В базах данных MongoDB данные объединяются в коллекции - collection. В одной базе данных может быть от одной до многих collections.
Смысл collection - объединять однотипные данные. То есть данные, котороые можно объединить по какому-либо признаку.
Например, в базе данных animals может быть две collections - cats и dogs. В коллекции cats хранятся все данные, о которых можно сказать - “это данные по кошкам”. В коллекции dogs хранятся “все данные по собакам”.
Создание collection
В базе данных создать collection можно командой:
Например, я создам две коллекции cats и dogs в базе данных animals. Для этого создам базу данных animals:
Создам коллекцию cats:
Создам коллекцию dogs:
Посмотреть список существующих колекций базы данных можно командой:
Проверю, создались ли успешно коллеции cats и dogs в базе данных animals:
Переименование collection
Операция переименования collection в MongoDB выполняется командой:
Например, я создал коллекцию bird в базе данных animals:
… и хочу переименовать эту коллецию в birds:
В результате коллекция bird успешно переименована в birds.
Удаление collection
В MongoDB удаление коллекции выполняется командой:
Например, я хочу удалить коллекцию birds из базы данных animals:
Коллекция birds успешно удалена из базы данных.
Создание collection - автоматический способ
В MongoDB имеется способ автоматического создания collection - путем добавления документа в новую коллецию при помощи метода insert.
Например, коллекции insects в базе данных animals не существует. В будущую коллекцию insects я добавлю документ cockroach и тем самым автоматически создам коллецию insects: