Беларусь, рогачёв |
Опубликован: 23.12.2005 | Уровень: специалист | Доступ: платный | ВУЗ: Московский физико-технический институт
Лекция 6:
Классы
Как на самом деле работает new
Итак, как мы теперь понимаем, оператор new производит пять операций.
- Создает новый (пустой) объект.
- Устанавливает ссылку __proto__, чтобы она указывала на прототип (это и делает объект принадлежащим к данному классу ).
- Устанавливает (недокументированную) ссылку constructor - она будет указывать на конструктор класса.
- Устанавливает (недокументированную) ссылку __constructor__ - она будет указывать на конструктор базового класса.
- Вызывает для вновь созданного объекта конструктор и передает ему указанные аргументы.
Исправляем эмуляцию new
А теперь, когда мы знаем детали работы new , мы можем исправить его эмуляцию. Давайте перепишем работу newFunc из последнего примера с лифтами и посмотрим, что получится.
_global.newFunc = function (constr, args){ var tmp = {}; // Или var tmp = new Object(); // Устанавливаем ссылки принадлежности к классу: tmp.__proto__ = constr.prototype; tmp.constructor = constr; // Детали работы этой строчки мы разберем // в лекции о наследовании. tmp.__constructor__ = constr.prototype.constructor; // Выделяем субмассив с аргументами, которые надо // передать в конструктор (все, кроме нулевого - // это сам конструктор) и вызываем его: constr.apply(tmp, arguments.slice(1)); return tmp; } // Мы не переписываем сюда весь код лифта, // но напоминаем содержание тестового примера // Создаем 2 объекта l1 = newFunc(lift, 2, 5); l2 = newFunc(lift, 0, 3); // Тестируем trace("l1:"); l1.goto(4); trace("l2:") l2.goto(4);
Запустив пример с этой исправленной функцией, получим:
l1: ----------- Закрываем двери. Этаж 2 Этаж 3 Этаж 4 Открываем двери. ----------- l2: ----------- Закрываем двери. Этаж 1 Этаж 2 Этаж 3 Открываем двери. -----------
Таким образом, видим, что лифты ездят как надо, хотя мы не скопировали в них ни единого поля из прототипа.