русс | укр

Языки программирования

ПаскальСиАссемблерJavaMatlabPhpHtmlJavaScriptCSSC#DelphiТурбо Пролог

Компьютерные сетиСистемное программное обеспечениеИнформационные технологииПрограммирование

Все о программировании


Linux Unix Алгоритмические языки Аналоговые и гибридные вычислительные устройства Архитектура микроконтроллеров Введение в разработку распределенных информационных систем Введение в численные методы Дискретная математика Информационное обслуживание пользователей Информация и моделирование в управлении производством Компьютерная графика Математическое и компьютерное моделирование Моделирование Нейрокомпьютеры Проектирование программ диагностики компьютерных систем и сетей Проектирование системных программ Системы счисления Теория статистики Теория оптимизации Уроки AutoCAD 3D Уроки базы данных Access Уроки Orcad Цифровые автоматы Шпаргалки по компьютеру Шпаргалки по программированию Экспертные системы Элементы теории информации

Прототипы и наследование


Дата добавления: 2015-07-09; просмотров: 467; Нарушение авторских прав


 

В главе 8 говорилось, что метод – это функция, которая вызывается как свойст_ во объекта. Когда функция вызывается таким способом, объект, посредством ко_ торого производится вызов, становится значением ключевого слова this. Пред_ положим, что необходимо рассчитать площадь прямоугольника, представленно_ го объектом Rectangle. Вот один из возможных способов:


function computeAreaOfRectangle(r) { return r.width * r.height; }


 

9.2. Прототипы и наследование
   

 

Эта функция прекрасно справляется с возложенными на нее задачами, но она не является объектно_ориентированной. Работая с объектом, лучше всего вызывать методы этого объекта, а не передавать объекты посторонним функциям в качест_ ве аргументов. Этот подход демонстрируется в следующем фрагменте:

// Создать объект Rectangle

 

var r = new Rectangle(8.5, 11); // Добавить к объекту метод

 

r.area = function() { return this.width * this.height; } // Теперь рассчитать площадь, вызвав метод объекта

 

var a = r.area();

 

Конечно же, не совсем удобно добавлять новый метод к объекту перед его ис_ пользованием. Однако ситуацию можно улучшить, если инициализировать свойство area в функции_конструкторе. Вот как выглядит улучшенная реализа_ ция конструктора Rectangle():

function Rectangle(w, h) {

this.width = w;

this.height = h;

this.area = function( ) { return this.width * this.height; }

}

 

С новой версией конструктора тот же самый алгоритм можно реализовать по_ другому:

 

// Найти площадь листа бумаги формата U.S. Letter в квадратных дюймах

var r = new Rectangle(8.5, 11);

var a = r.area();

 

Такое решение выглядит гораздо лучше, но оно по_прежнему не является опти_ мальным. Каждый созданный прямоугольник будет иметь три свойства. Свойст_ ва width и height могут иметь уникальные значения для каждого прямоугольни_ ка, но свойство area каждого отдельно взятого объекта Rectangle всегда будет ссылаться на одну и ту же функцию (разумеется, это свойство можно изменить в процессе работы, но, как правило, предполагается, что методы объекта не должны меняться). Применение отдельных свойств для хранения методов объ_ ектов, которые могли бы совместно использоваться всеми экземплярами одного и того же класса, – это достаточно неэффективное решение.



 

Однако и эту проблему можно решить. Оказывается, все объекты в JavaScript содержат внутреннюю ссылку на объект, известный как прототип. Любые свой_ ства прототипа становятся свойствами другого объекта, для которого он являет_ ся прототипом. То есть, говоря другими словами, любой объект в JavaScript на' следует свойства своего прототипа.

 

В предыдущем разделе было показано, как оператор new создает пустой объект и затем вызывает функцию_конструктор. Но история на этом не заканчивается. После создания пустого объекта оператор new устанавливает в этом объекте ссыл_ ку на прототип. Прототипом объекта является значение свойства prototype функции_конструктора. Все функции имеют свойство prototype, которое ини_ циализируется в момент определения функции. Начальным значением этого свойства является объект с единственным свойством. Это свойство называется constructor и значением его является ссылка на саму функцию_конструктор,


 

168 Глава 9. Классы, конструкторы и прототипы

с которой этот прототип ассоциируется. (Описание свойства constructor приводи_ лось в главе 7, здесь же объясняется, почему каждый объект обладает свойством constructor.) Любые свойства, добавленные к прототипу, автоматически стано_ вятся свойствами объектов, инициализируемых конструктором.

Более понятно это можно объяснить на примере. Вот новая версия конструктора

Rectangle():

 

// Функция_конструктор инициализирует те свойства, которые могут

 

// иметь уникальные значения для каждого отдельного экземпляра. function Rectangle(w, h) {

 

this.width = w; this.height = h;

 

}

// Прототип объекта содержит методы и другие свойства, которые должны

 

// совместно использоваться всеми экземплярами этого класса. Rectangle.prototype.area = function() { return this.width * this.height; }

 

Конструктор определяет «класс» объектов и инициализирует свойства, такие как width и height, которые могут отличаться для каждого экземпляра класса. Объект_ прототип связан с конструктором, и каждый объект, инициализируемый конст_ руктором, наследует тот набор свойств, который имеется в прототипе. Это значит, что объект_прототип – идеальное место для методов и других свойств_констант.

 

Обратите внимание, что наследование осуществляется автоматически как часть процесса поиска значения свойства. Свойства не копируются из объекта_прото_ типа в новый объект; они просто присутствуют, как если бы были свойствами этих объектов. Это имеет два важных следствия. Во_первых, использование объ_ ектов_прототипов может в значительной степени уменьшить объем памяти, тре_ буемый для каждого объекта, т. к. объекты могут наследовать многие из своих свойств. Во_вторых, объект наследует свойства, даже если они были добавлены в прототип после создания объекта. Это означает наличие возможности добав_ лять новые методы к существующим классам (хотя это не совсем правильно).

 

Унаследованные свойства ничем не отличаются от обычных свойств объекта. Они поддаются перечислению в цикле for/in и могут проверяться с помощью опе_ ратора in. Отличить их можно только с помощью метода Object.hasOwnProperty():

 

var r = new Rectangle(2, 3);

r.hasOwnProperty("width"); // true: width – непосредственное свойство "r"
r.hasOwnProperty("area"); // false: area – унаследованное свойство "r"
"area" in r; // true: area – свойство объекта "r"

 



<== предыдущая лекция | следующая лекция ==>
Конструкторы | Чтение и запись унаследованных свойств


Карта сайта Карта сайта укр


Уроки php mysql Программирование

Онлайн система счисления Калькулятор онлайн обычный Инженерный калькулятор онлайн Замена русских букв на английские для вебмастеров Замена русских букв на английские

Аппаратное и программное обеспечение Графика и компьютерная сфера Интегрированная геоинформационная система Интернет Компьютер Комплектующие компьютера Лекции Методы и средства измерений неэлектрических величин Обслуживание компьютерных и периферийных устройств Операционные системы Параллельное программирование Проектирование электронных средств Периферийные устройства Полезные ресурсы для программистов Программы для программистов Статьи для программистов Cтруктура и организация данных


 


Не нашли то, что искали? Google вам в помощь!

 
 

© life-prog.ru При использовании материалов прямая ссылка на сайт обязательна.

Генерация страницы за: 1.1 сек.