Скачать 1.04 Mb.
|
^ Создание пользовательского объекта с помощью инициализатора имеет тот существенный недостаток, что для каждого, даже однотипного, объекта приходится задавать свой инициализатор. Использование для создания пользовательского объекта функцию-конструктор позволяет с ее помощью создавать экземпляры объектов, аналогично тому, как это делается для встроенных объектов JavaScript. В функции-конструкторе функции определяются свойства и методы для данного объекта. Определение этой функции в JavaScript имеет следующий синтаксис: function имя-объектного-типа(параметр-1, параметр-2,...) { this.свойство-1 = параметр-1; this.свойство-2 = параметр-2; ... this.имя-метода-1 = имя-функции-1; this.имя-метода-2 = function(список-параметров-1) {тело-функции-1}; ... } Как видно из приведенного определения свойства объекту присваиваются с помощью параметров, однако это не является обязательным. Свойства объекту могут быть присвоены внутри функции-конструктора, например, с помощью выражений, как в инициализаторе объекта. Далее в функции-конструкторе следуют предложения, определяющие методы для данного объектного типа. Функции для этих методов можно двумя способами: с помощью отдельной функции и непосредственно в предложении определения метода. При первом способе в предложении задания метода указывается, что для выполнения метода с именем имя-метода будет вызвана функция с именем имя-функции. (как это сделано для первого метода). Функции для методов данного объекта определяются отдельно: function имя-функции-1(параметры-1) { тело функции-1 } При втором способе можно прямо определить функцию для метода, как это делается в инициализаторе объекта. Создание нового экземпляра объекта выполняется с помощью предложения new: var имя-объекта = new имя-объектного-типа(аргумент-1, аргумент-2,...) Обращение к свойствам и методам созданного объекта выполняется с использованием точечной нотации: имя-объекта.свойство-1 имя-объекта.метод-1(агрументы-1) Язык JavaScript поддерживает объекты, свойствами которых, в свою очередь, могут быть другие объекты. Пример 4.4.64. Использование функции-конструктора: 1. // Функция-конструктор объектного типа Point function Point(x, y) { this.x = x; // Свойство x: координата x точки this.y = y; // Свойство y: координата y точки // Метод assign - присваивание координат точки this.assign = assignValue; // Метод move - перемещение точки this.move = movePoint; // Метод toString - строковое представление точки this.toString = function() { return "(" + this.x + "," + this.y + ")"; } } // Функция assignValue, реализующая метод assign function assignValue(x, y) { // Присваивание значения координате x точки this.x = x; // Присваивание значения координате y точки this.y = y; // Возврат объекта return this; } // Функция movePoint, реализующая метод move function movePoint(dx, dy) { // Перемещение точки на заданное // приращение по оси x this.x += dx; // Перемещение точки на заданное // приращение по оси y this.y += dy; } … // Создание объекта point1 типа Point point1 = new Point(3, 4); // Вывод свойств объекта point1 alert("point1: x=" + point1.x + " y=" + point1.y); // Создание объекта point2 типа Point point2 = new Point(-3, 5); // Создание объекта point3 типа Point point3 = point2; // Вывод объектов point1, point2 и point3 alert("point1=" + point1 + " point2=" + point2 + " point3=" + point3); // Присвоение point1 нового значения point1.assign(7,10); // Перемещение point3 point3.move(3,-3); // Вывод объектов point1, point2 и point3 alert("point1=" + point1 + " point2=" + point2 + " point3=" + point3); В этом фрагменте сценария с помощью функции-конструктора определен пользовательский объект ^ с теми же свойствами и методами, что и в примере 4.4.63(1), а затем созданы два объекта типа Point – point1 и point2. Во фрагменте также создан объект point3, связанный с объектом point2 и выводятся характеристики объектов до и после изменения значений объектов point1 и point3. Вывод этого фрагмента имеет следующий вид:
2. // Функция-конструктор объектного типа Line function Line(Point, Point) { // Координаты x и y начала линии // (использован объект типа Point) this.coord1 = arguments[0]; // Координаты x и y окончания линии // (использован объект типа Point) this.coord2 = arguments[1]; // Метод определения длины линии this.length = getLength; // Метод преобразования // объекта Line в строку this.toString = function() { return "(" + this.coord1.toString() + "," + this.coord2.toString() + ")"; } } // Функция getLength, реализующая метод length function getLength() { // Определение и возврат длины линии return Math.sqrt(Math.pow(this.coord1.x - this.coord2.x, 2) + Math.pow(this.coord1.y - this.coord2.y, 2)); } … // Создание объекта line1 типа Line var line1 = new Line(new Point(3,4), new Point(7,8)); // Вывод текущих значений свойств // coord1 и coord2 объекта line1 alert("line1: x=" + line1.coord1.toString() + " y=" +line1.coord2.toString()); // Задание начальной точки линии line2 point1 = new Point(0,3); // Задание конечной точки линии line2 point2 = new Point(3,0); // Создание объекта line2 типа Line var line2 = new Line(point1, point2); // Вывод координат и длины line1 и line2 alert("line1=" + line1.toString() + " Длина: " + line1.length() + "\nline2=" + line2.toString() + " Длина: " + line2.length()); В этом фрагменте сценария с помощью функции-конструктора определен пользовательский объект Line с теми же свойствами и методами, что и в примере 4.4.63(2), а затем созданы два объекта типа Line – line11 и line2. Во фрагменте также выводятся свойства объекта line1, а затем строковое представление объектов line1 и line2 и их длины. Вывод этого фрагмента имеет следующий вид:
Как отмечалось выше (см. 4.4.9), в объектно-ориентированном программировании классы образуют иерархическую систему, т.е. одни классы являются наследниками других классов. Одним из преимуществ объектно-ориентированного подхода является понятие наследования свойств и методов классов-предков в классах-потомках. Это означает, что в классе-потомке можно использовать свойства и методы, определенные в классах-предках. Если свойство или метод в каком-либо классе-потомке имеет другой значение и алгоритм реализации, их следует переопределить в этом классе с тем же именем. Механизм наследования в классе-потомке реализуется следующим образом: при использовании для объекта в классе-потомке какого-либо свойства или вызове метода, используется свойство или метод данного класса, если они определены в этом классе, иначе классы просматриваются вверх по иерархии и ищется ближайшее определение данного свойства или метода. Найденное свойство подставляется в выражении для свойства, а метод вызывается с заданными параметрами. Напрямую наследование не реализовано в JavaScript, однако, используя методы call() и apply() объекта Function, можно реализовать описанный выше механизм. Функция call(параметр, аргумент-1, аргумент-2,…) вызывает метод другого объекта с целью выполнения его для данного объекта. Аргумент параметр задает параметр для вызывающего объекта (обычно ключевое слово this, т.е. вызов для данного объекта). Остальные аргументы: аргумент-1, аргумент-2 и другие задают аргументы, необходимые для вызова заданной функции-конструктора или метода другого объекта. Функция apply(параметр, аргументы) действует аналогичным образом, но во втором аргументе задается объект типа ^ , содержащий список передаваемых при вызове аргументов. Если функции call() или apply() применены к функции-конструктору какого-либо объекта, все методы и свойства этого объекта становятся доступным в объекте, вызвавшем функцию call()или apply(), если они не переопределены в вызвавшем объекте. Таким образом, применение этих функций позволяет неявно создавать иерархию классов в JavaScript с использованием механизма наследования. Пример 4.4.65. Использование иерархии объектов в JavaScript: // Объявления глобальной переменной // для имени объекта objectName = ""; // Объявления глобальной переменной // для строки сообщений о вызове функций callOutput = "" // Функция-конструктор объекта // Rectangle (прямоугольник) function Rectangle(a, b) { // Свойство a: одна сторона прямоугольника this.a = a; // Свойство b: другая сторона прямоугольника this.b = b; // Метод определения периметра прямоугольника this.perimeter = function() { // Вывод в строку сообщений о вызове функций callOutput += "\n Rectangle.perimeter для " + objectName // Вычисление и возврат // периметра прямоугольника return 2*this.a + 2*this.b; } // Метод определения площади прямоугольника this.area = function() { // Вывод в строку сообщений о вызове функций callOutput += "\n Rectangle.area для " + objectName; // Вычисление и возврат // площади прямоугольника return this.a*this.b; } // Метод преобразования объекта Rectangle в строку this.toString = function() { // Вывод в строку сообщений о вызове функций callOutput += "\n Rectangle.toString для " + objectName // Преобразование свойств прямоугольника // в строку return "(" + this.a + "," + this.b + ")"; } } // Функция-конструктор объекта // Square (квадрат) function Square(a) { // Вызов конструктора объекта Rectangle ^ // Метод определения площади для квадрата this.area = function() { // Вывод в строку сообщений о вызове функций callOutput += "\n Square.area для " + objectName // Вычисление и возврат площади квадрата return this.a*this.a; } } // Функция-конструктор объекта // Rhomb (ромб) function Rhomb(a, alpha) { // Свойство alpha: угол между сторонами ромба this.alpha = alpha; // Вызов конструктора объекта Square Square.apply(this, arguments); // Метод определения площади ромба this.area = function() { // Вывод в строку сообщений о вызове функций callOutput += "\n Rhomb.area для " + objectName // Вычисление и возврат площади ромба return this.a*this.a*Math.sin(Math.PI*alpha/180); } // Метод преобразования объекта Rhomb в строку this.toString = function() { // Вывод в строку сообщений о вызове функций callOutput += "\n Rhomb.toString для " + objectName // Преобразование свойств объекта Rhomb // в строку return "(" + this.a + "," + this.alpha + ")"; } } … // Определение объекта Rectangle // как прототипа для объекта Square ^ // Определение объекта Square // как прототипа для объекта Rhomb Rhomb.prototype = Square.prototype; … // Создание объекта rectangle1 типа Rectangle rectangle1 = new Rectangle(3,5); // Задание имени объекта для rectangle1 objectName="rectangle1"; // Вывод характеристик объекта rectangle1 alert("rectangle1=" + rectangle1.toString() + " Периметр: " + rectangle1.perimeter() + " Площадь: " + rectangle1.area()); // Вывод списка вызовов функций // для объекта rectangle1 alert("Вызовы функций: " + callOutput); // Создание объекта square1 типа Square square1 = new Square(5); // Чистка списка вызовов функций callOutput = ""; // Задание имени объекта для square1 objectName="square1"; // Вывод характеристик объекта square1 alert("square1=" + square1.toString() + " Периметр: " + square1.perimeter() + " Площадь: " + square1.area()); // Вывод списка вызовов функций // для объекта square1 alert("Вызовы функций: " + callOutput); // Создание объекта rhomb1 типа Rhomb rhomb1 = new Rhomb(5, 45); // Чистка списка вызовов функций callOutput = ""; // Задание имени объекта для rhomb1 objectName="rhomb1"; // Вывод характеристик объекта rhomb1 alert("rhomb1=" + rhomb1.toString() + " Периметр: " + rhomb1.perimeter() + " Площадь: " + rhomb1.area()); // Вывод списка вызовов функций // для объекта square1 alert("Вызовы функций: " + callOutput); // Определение и вывод прототипов объектов alert("Square - прототип объекта square1?" + " Ответ: " + Square.prototype.isPrototypeOf(square1) + "\nRectangle - прототип объекта square1?" + " Ответ: " + Rectangle.prototype.isPrototypeOf(square1) + "\nRhomb - прототип объекта rhomb1?" + " Ответ: " + Rhomb.prototype.isPrototypeOf(rhomb1) + "\nSquare - прототип объекта rhomb1?" + " Ответ: " + Square.prototype.isPrototypeOf(rhomb1) + "\nRectangle - прототип объекта rhomb1?" + " Ответ: " + Rectangle.prototype.isPrototypeOf(rhomb1)); В этом фрагменте сценария задана иерархия объектов Rectangle (прямоугольник), Square (квадрат) и Rhomb (ромб), представленная на рис. 4.4.1. ![]() Рис. 4.4.1. Иерархия классов Rectangle, Square и Rhomb Для объекта Rectangle определены свойства a и b, а также методы perimeter(), area() и toString(). Для создания экземпляра объекта Square в функции-конструкторе этого объекта вызывается функция-конструктор объекта Rectangle. Кроме этого, для объекта Square переопределен метод area(). Для создания экземпляра объекта ^ в функции-конструкторе этого объекта вызывается функция-конструктор объекта Square. Кроме этого, для объекта Rhomb переопределены метод area() и toString(). Вывод характеристик созданных объектов rectangle1, square1 и rhomb1, вызываемые функции при выводе этих объектов, а также прототипы для созданных объектов, полученные с помощью свойства prototype объекта Object (см. 4.4.11.9.2), приведены ниже:
|
![]() | Создание документа (размеры, цвет фона, частота кадров). Выравнивание объектов в документе | ![]() | Дополнения к Перечню объектов коммунальной собственности, включенных в перечни объектов |
![]() | Ия 17 объектов коммунальной собственности. С учетом 6-и объектов, переходящих из Перечня объектов, подлежащих приватизации в 2005... | ![]() | Цель работы: Изучить основные виды и способы анимации параметров объектов в 3d studio max: анимация по ключевым кадрам, анимация... |
![]() | В отличие от финансовых инвестиций, недвижимость имеет явно выраженную материальную форму, более высокий уровень защиты от инфляции,... | ![]() | Анализируя свойства этих простых трехмерных геометрических объектов можно сделать вывод о том, что форма каждого из них имеет свои... |
![]() | Инспектирование грузов и объектов (Агро сектор, Металлургия). Управление залоговым хранением. Техническое инспектирование объектов... | ![]() | Многократное копирование элементов и объектов. Полукруглые, круглые стены с возможностью редактирования. Загрузка объектов в режиме... |
![]() | Диаграммы объектов применяют при моделировании статических видов системы с точки зрения проектирования и процессов. При этом моделируется... | ![]() | Целью Программы является создание банка данных для обеспечения органов исполнительной власти полноразмерными копиями документов и... |