Вход/Регистрация
JavaScript. Подробное руководство, 6-е издание
вернуться

Флэнаган Дэвид

Шрифт:

// Вернуть имя конструктора объекта, если имеется

if (о.constructor && typeof о.constructor === "function" &&

(n = о.constructor.getName)) return n;

// He удалось определить конкретный тип, поэтому остается лишь

// просто вернуть "Object"

return "Object";

}

// Возвращает класс объекта,

function classof(o) {

return Object.prototype.toString.call(о).slice(8,-1);

};

// Возвращает имя функции (может быть "") или null - для объектов,

// не являющихся функциями

Function.prototype.getName = function {

if ("name" in this) return this.name;

return this.name = this.toString.match(/function\s*([^(]*)\(/)[1];

):

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

constructor
: не все объекты имеют свойство
constructor
. Кроме того, не все функции имеют имена. Если определить конструктор, используя выражение определения неименованной функции, метод
getName
будет возвращать пустую строку:

// Этот конструктор не имеет имени

var Complex = function(x,у) { this.r = х; this.і = у; }

// Этот конструктор имеет имя

var Range = function Range(f.t) { this.from = f; this.to = t; }

9.5.4. Грубое определение типа

Ни один из приемов определения класса объекта, описанных выше, не свободен от проблем, по крайней мере, в клиентском JavaScript. Альтернативный подход состоит в том, чтобы вместо вопроса «какому классу принадлежит объект?» задать вопрос «что может делать этот объект?». Этот подход является типичным в таких языках программирования, как Python и Ruby, и носит название грубое определение типа (<duck-typing, или «утиная типизация») в честь высказывания (часто приписываемого поэту Джеймсу Уиткомбу Райли (James Whitcomb Riley)):

Когда я вижу птицу, которая ходит, как утка, плавает, как утка и крякает, как утка, я называю ее уткой.

Для программистов на языке JavaScript этот афоризм можно интерпретировать так: «Если объект может ходить, плавать и крякать как объект класса Duck, его можно считать объектом класса Duck, даже если он не наследует объект-прототип класса Duck».

Примером может служить класс

Range
из примера 9.2. Этот класс предназначен для представления диапазонов чисел. Однако обратите внимание, что конструктор
Range
не проверяет типы аргументов, чтобы убедиться, что они являются числами. Аналогично метод
includes
использует оператор
<=
, но не делает никаких предположений о типах значений границ диапазона. Благодаря тому что класс не ограничивается определенным типом значений, его метод
includes
способен обрабатывать значения границ любых типов, которые могут сравниваться с помощью операторов отношения:

var lowercase = new Range("a", 'z');

var thisYear = new Range(new Date(2009, 0, 1), new Date(2010, 0, 1));

Метод

foreach
класса
Range
также не проверяет типы значений границ, но он использует функцию
Math.ceil
и оператор
++
, вследствие чего может применяться только к числовым значениям границ диапазона.

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

Array
: вполне достаточно знать, что он имеет свойство
length
с неотрицательным целочисленным значением. Если посчитать, что целочисленное свойство
length
– это способ массивов «ходить», то мы могли бы сказать, что любой объект, который умеет «ходить» так же, можно (во многих случаях) отнести к массивам.

Однако имейте в виду, что свойство

length
настоящих массивов обладает особым поведением: свойство
length
автоматически обновляется при добавлении нового элемента, а когда значение свойства
length
уменьшается, массив автоматически усекается. Можно было бы сказать, что эти две особенности описывают, как массивы «плавают» и «крякают». Если вы пишете программу, где требуется, чтобы объект «плавал» и «крякал» как массив, вы не сможете использовать в ней объект, который только «ходит» как массив.

  • Читать дальше
  • 1
  • ...
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: