Утка набирает в JavaScript

  1. Вебинар: По запросу, по требованию Настольный компьютер как услуга, разработанный для любого облака?...
  2. Эмуляция интерфейсов с Duck Typing
  3. Защита от самозванцев
  4. Заключение

Вебинар:
По запросу, по требованию

Настольный компьютер как услуга, разработанный для любого облака? Рамка Нутаникс


в Обезьяна Ямочный В статье я ввел термин «Duck Typing». Duck Typing, созданный Ruby-программистами, основан на принципе: «Если он ходит как утка и крякает как утка, значит, это утка». Следуя этому принципу, вместо того, чтобы пытаться определить пригодность объекта для данной цели в соответствии с его типом, при типизации утки пригодность объекта определяется наличием определенных методов и свойств. Когда вы ознакомитесь с этой концепцией, вы начнете замечать, где Duck Typing использовался во многих языках программирования, включая JavaScript, с большим успехом. В сегодняшней статье мы проследим его эволюцию в JavaScript и рассмотрим некоторые ситуации, в которых мы можем применять Duck Typing для наших собственных целей.

Утка набирает корни в JavaScript

Когда-то авторы сценариев использовали технику, называемую «Обнюхивание обозревателя», то есть анализ пользовательского агента, чтобы определить, следует ли кодировать в JavaScript (Netscape) или JScript (Internet Explorer). Со временем эту практику затмил Обнаружение функций, в результате чего была выбрана конкретная функция / возможность. Например:

// Обнаружение браузера if (navigator.userAgent.indexOf ("MSIE 7")> -1) {// сделать что-то} // Обнаружение функции if (document.all) {// сделать что-то}

Обнаружение функций стало заметным улучшением по сравнению с анализатором браузера, но, к сожалению, многие веб-разработчики пошли еще дальше, используя тест document.all в качестве неявной проверки для Internet Explorer. Предполагая, что браузер на самом деле является IE, кодировщики затем будут исходить из ошибочного предположения о том, что было также безопасно использовать другие специфичные для IE методы и свойства, такие как свойство document.uniqueID. В Duck Typing нельзя было бы делать такие предположения на основе какого-либо конкретного теста.

Позже, несколько шайба библиотеки были разработаны для стандартизированного определения функций HTML5 и CSS3 в различных браузерах. Наиболее известным из них является Modernizr. Модернизр, созданный несколькими разработчиками, включая Пола Айриша, получил несколько наград. Он создает глобальный объект Modernizr, который содержит набор логических свойств для каждой функции, которую он может обнаружить. Например, если браузер поддерживает API Canvas, для свойства Modernizr.canvas будет установлено значение true , иначе - false :

if (Modernizr.canvas) {// давайте нарисуем несколько фигур ...! } else {// нет собственной поддержки canvas :(}

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

Эмуляция интерфейсов с Duck Typing

Интерфейсы являются одной из самых мощных функций языков программирования, таких как Java. Это файл, который содержит коллекцию сигнатур функций. Когда объект реализует интерфейс, он символически подписывает контракт, в соответствии с которым он соглашается выполнять определенные действия (функции) интерфейса. Если объект не соответствует своей стороне сделки, ваша программа даже не скомпилируется!

Хотя JavaScript не является объектно-ориентированным языком, как Java (он использует прототипное наследование), есть способы эмулировать интерфейсоподобные функции. Посмотрим как.

Для нашей демонстрации давайте создадим три типа автомобилей:

функция Infiniti (модель) {this.model = модель; } функция Honda (модель) {this.model = model; } function Hyundai (model) {this.model = model; }

Мы можем создать экземпляр каждого типа Car, используя ключевое слово new, передавая его тип:

var cars = [новый Infiniti («G37»), новая Honda («Civic»), новый Hyundai («Accent»)];

Предположим, мы хотели участвовать в гонках наших автомобилей. Мы могли бы написать что-то вроде этого, где описано ускорение каждого автомобиля:

function race (car) {if (car instanceof Infiniti) {console.log (car.model + ": очень быстро разгоняешься от 0 до 60 миль в час!"); } else if (автомобиль экземпляра Honda) {console.log (car.model + ": движение от 0 до 60 миль в час на умеренной скорости."); } else if (car instanceof Hyundai) {console.log (car.model + ": переход от 0 до 60 миль в час при сканировании."); }} // Давайте гонять на некоторых машинах! for (var i in cars) {гонки (cars [i]); } / * выводит: "G37: очень быстро разгоняется от 0 до 60 миль в час!" «Civic: движение от 0 до 60 миль в час на умеренной скорости». «Акцент: движение от 0 до 60 миль в час при ползании». * * /

* Нет неуважения к владельцам Hyundai Accents. Я просто высмеиваю своего приятеля!

Оператор instanceof проверяет определенные типы автомобилей и выводит соответствующий текст.

Хотя в приведенном выше коде нет ничего технически неправильного, существует довольно серьезный недостаток дизайна, заключающийся в том, что каждый раз, когда мы создаем новый тип автомобиля, мы должны обновлять функцию race ()!

Излишне говорить, что есть лучший способ настроить функцию race () для различных типов автомобилей.

Давайте представим, что типы автомобилей должны реализовывать метод ускорения (), специфичный для данного типа автомобилей. Затем в функции race () мы можем просто передать экземпляр Car в функцию race (), чтобы он, в свою очередь, мог вызвать метод accelerate () объекта:

функция Infiniti (модель) {this.model = модель; } Infiniti.prototype.accelerate = function () {console.log (this.model + ": очень быстрый переход от 0 до 60 миль в час!"); } функция Honda (модель) {this.model = model; } Honda.prototype.accelerate = function () {console.log (this.model + ": движение от 0 до 60 миль в час на умеренной скорости."); } function Hyundai (model) {this.model = model; } Hyundai.prototype.accelerate = function () {console.log (this.model + ": переход от 0 до 60 миль в час при сканировании."); } function race (car) {// Динамически вызывать метод accelerate () // любого автомобиля, в который был передан. car.accelerate (); } // Давайте гонять на некоторых машинах! var cars = [новый Infiniti («G37»), новая Honda («Civic»), новый Hyundai («Accent»)]; for (var i in cars) {гонки (cars [i]); }

Защита от самозванцев

Поскольку в JavaScript отсутствует проверка компилятором языков программирования, таких как Java, все равно не мешало бы проверить, что переданный объект действительно может ускоряться и выдает ошибку, если не может. Для иллюстрации мы передадим кушетку функции race ():

function race (car) {// Динамически вызывать метод accelerate () // любого автомобиля, в который был передан. if (car.accelerate) car.accelerate (); еще бросить новый DuckTypeError («Эй, ты не машина!»); } // попробуем погонять на диване !? function Couch (type) {this.type = type; } раса (новый Couch («Диван»));

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

G37: очень быстро с 0 до 60 миль в час! Civic: движение от 0 до 60 миль в час на умеренной скорости. Акцент: движение от 0 до 60 миль в час при ползании. SCRIPT5022: DuckTypeError: Эй, ты не машина! index.html (71,7)

Duck Typing гарантирует, что наш объект «крякает как утка». Преимущество этого подхода заключается в том, что нам не нужно вносить какие-либо дальнейшие обновления функции race () для соответствия новым типам автомобилей.

Заключение

В сегодняшней статье мы проследили эволюцию Duck Typing в JavaScript и выяснили, как использовать Duck Typing для эмуляции поведения Java-интерфейсов в объектах JS. Есть полный демонстрация на Codepen для вас, чтобы исследовать.


Роб Гравелль проживает в Оттаве, Канада. Его проектная компания построил веб-приложения для многочисленных предприятий и государственных учреждений. Напишите ему ,

Альтер-эго Роба "Blackjacques" - опытный гитарист, выпустивший несколько компакт-дисков и кавер-версии песен. Журнал Brave Words (выпуск № 92) назвал его группу Ivory Knight одной из лучших канадских хард-рок и метал групп.


Вебинар: По запросу, по требованию Настольный компьютер как услуга, разработанный для любого облака?