Описание механизма наследования свойств приводится в разделе 6.2.2. Как получить ссылку на прототип объекта, рассказывается в разделе 6.8.1. А в главе 9 более детально будет обсуждаться связь между прототипами и конструкторами: там будет показано, как определять новые «классы» объектов посредством объявления функций-конструкторов и как записывать ссылку на объект-прототип в их свойство prototype для последующего использования «экземплярами», созданными с помощью этого конструктора.
6.1.4. Object.create()
Стандарт ECMAScript 5 определяет метод Object.create(), который создает новый объект и использует свой первый аргумент в качестве прототипа этого объекта. Дополнительно Object.create() может принимать второй необязательный аргумент, описывающий свойства нового объекта. Описание этого второго аргумента приводится в разделе 6.7.
Object.create() является статической функцией, а не методом, вызываемым относительно некоторого конкретного объекта. Чтобы вызвать эту функцию, достаточно передать ей желаемый объект-прототип:
var о1 = Object.create({x:1, у:2}); // о1 наследует свойства х и у.
Чтобы создать объект, не имеющий прототипа, можно передать значение null, но в этом случае вновь созданный объект не унаследует ни каких-либо свойств, ни базовых методов, таких как toString() (а это означает, что этот объект нельзя будет использовать в выражениях с оператором +):
var о2 = Object.create(null); // о2 не наследует ни свойств, ни методов.
Если в программе потребуется создать обычный пустой объект (который, например, возвращается литералом {} или выражением new Object()), передайте в первом аргументеObject.prototype:
var о2 = Object.create(Object.prototype); // о3 подобен объекту, созданному
// с помощью {} или new Object().
Возможность создавать новые объекты с произвольными прототипами (скажем иначе: возможность создавать «наследников» от любых объектов) является мощным инструментом, действие которого можно имитировать в ECMAScript 3 с помощью функции, представленной в примере 6.1.[8]
)
Пример 6.1. Создание нового объекта, наследующего прототип
// inherit() возвращает вновь созданный объект, наследующий свойства
// объекта-прототипа р. Использует функцию Object.create() из ECMAScript 5,
// если она определена, иначе используется более старый прием,
function inherit(р) {
if (р == null) throw ТуреЕrror(); // р не может быть значением null
if (Object.create) // Если Object.create() определена...
return Object.create(p); // использовать ее.
var t = typeof p; // Иначе выяснить тип и проверить его
if (t !== "object" && t !== "function") throw ТуреЕrror();
function f() {}; // Определить фиктивный конструктор,
f.prototype = p; // Записать в его свойство prototype
// ссылку на объект р.
return new f(); // Использовать f() для создания
// "наследника" объекта р.
}
Реализация функции inherit() приобретет больше смысла, как только мы познакомимся с конструкторами в главе 9. А пока просто считайте, что она возвращает новый объект, наследующий свойства объекта в аргументе. Обратите внимание, что функция inherit() не является полноценной заменой для Object.create(): она не позволяет создавать объекты без прототипа и не принимает второй необязательный аргумент, как Object.сreate(). Тем не менее мы будем использовать функцию inherit() во многих примерах в этой главе и в главе 9.
8
Дуглас Крокфорд (Douglas Crockford) считается первым, кто реализовал функцию, создающую объекты таким способом. См. http://javascript.crockford.com/prototypal.html.