| Беларусь, рогачёв |
Опубликован: 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 Открываем двери. -----------
Таким образом, видим, что лифты ездят как надо, хотя мы не скопировали в них ни единого поля из прототипа.