Перевод не завершен. Пожалуйста, помогите перевести эту статью с английского.
Метод Object.create()
создаёт новый объект с указанными объектом прототипа и свойствами.
Синтаксис
Object.create(proto[, propertiesObject])
Параметры
proto
- Объект, который станет прототипом вновь созданного объекта.
propertiesObject
- Необязательный параметр. Если указан и не равен
undefined
, должен быть объектом, чьи собственные перечисляемые свойства (то есть такие, которые определены на самом объекте, а не унаследованы по цепочке прототипов) указывают дескрипторы свойств, добавляемых в новый объект. Имена добавляемых свойств совпадают с именами свойств в этом объекте. Эти свойства соответствуют второму аргументу методаObject.defineProperties()
.
Выбрасываемые исключения
Выбрасывает исключение TypeError
, если параметр proto
не является null
или объектом.
Примеры
Пример: классическое наследование с Object.create()
Ниже показан пример использования Object.create()
для имитации классического наследования. Это пример одиночного наследования, поскольку только его поддерживает JavaScript.
// Shape — суперкласс function Shape() { this.x = 0; this.y = 0; } // метод суперкласса Shape.prototype.move = function(x, y) { this.x += x; this.y += y; console.info('Фигура переместилась.'); }; // Rectangle — подкласс function Rectangle() { Shape.call(this); // вызываем конструктор суперкласса } // подкласс расширяет суперкласс Rectangle.prototype = Object.create(Shape.prototype); Rectangle.prototype.constructor = Rectangle; var rect = new Rectangle(); console.log('Является ли rect экземпляром Rectangle? ' + (rect instanceof Rectangle)); // true console.log('Является ли rect экземпляром Shape? ' + (rect instanceof Shape)); // true rect.move(1, 1); // выведет 'Фигура переместилась.'
Если вы хотите унаследоваться от нескольких объектов, то это возможно сделать при помощи примесей.
function MyClass() { SuperClass.call(this); OtherSuperClass.call(this); } MyClass.prototype = Object.create(SuperClass.prototype); // наследование mixin(MyClass.prototype, OtherSuperClass.prototype); // примешивание MyClass.prototype.myMethod = function() { // что-то делаем };
Функция примешивания должна копировать функции из прототипа суперкласса в прототип подкласса, она должна предоставляться пользователем. Примером примеси может служить функция jQuery.extend().
Пример: использование аргумента propertiesObject
с Object.create()
var o; // создаём объект с нулевым прототипом o = Object.create(null); o = {}; // эквивалентно этому: o = Object.create(Object.prototype); // В этом примере мы создаём объект с несколькими свойствами. // (Обратите внимание, что второй параметр отображает ключи на *дескрипторы свойств*.) o = Object.create(Object.prototype, { // foo является рядовым 'свойством-значением' foo: { writable: true, configurable: true, value: 'привет' }, // bar является свойством с геттером и сеттером (свойством доступа) bar: { configurable: false, get: function() { return 10; }, set: function(value) { console.log('Установка `o.bar` в', value); } /* при использовании методов доступа ES5 наш код мог бы выглядеть так: get function() { return 10; }, set function(value) { console.log('Установка `o.bar` в', value); } */ } }); function Constructor() {} o = new Constructor(); // эквивалентно этому: o = Object.create(Constructor.prototype); // Конечно, если бы в функции Constructor был бы реальный код инициализации, // метод с Object.create() не был бы эквивалентным // создаём новый объект, чей прототип является новым пустым объектом // и добавляем простое свойство 'p' со значением 42 o = Object.create({}, { p: { value: 42 } }); // по умолчанию свойства НЕ ЯВЛЯЮТСЯ записываемыми, перечисляемыми или настраиваемыми: o.p = 24; o.p; // 42 o.q = 12; for (var prop in o) { console.log(prop); } // 'q' delete o.p; // false // для определения свойства ES3 o2 = Object.create({}, { p: { value: 42, writable: true, enumerable: true, configurable: true } });
Полифилл
Для этого полифилла необходима правильно работающая Object.prototype.hasOwnProperty.
if (typeof Object.create != 'function') { // Production steps of ECMA-262, Edition 5, 15.2.3.5 // Reference: https://es5.github.io/#x15.2.3.5 Object.create = (function() { // To save on memory, use a shared constructor function Temp() {} // make a safe reference to Object.prototype.hasOwnProperty var hasOwn = Object.prototype.hasOwnProperty; return function (O) { // 1. If Type(O) is not Object or Null throw a TypeError exception. if (typeof O != 'object') { throw TypeError('Object prototype may only be an Object or null'); } // 2. Let obj be the result of creating a new object as if by the // expression new Object() where Object is the standard built-in // constructor with that name // 3. Set the [[Prototype]] internal property of obj to O. Temp.prototype = O; var obj = new Temp(); Temp.prototype = null; // Let's not keep a stray reference to O... // 4. If the argument Properties is present and not undefined, add // own properties to obj as if by calling the standard built-in // function Object.defineProperties with arguments obj and // Properties. if (arguments.length > 1) { // Object.defineProperties does ToObject on its first argument. var Properties = Object(arguments[1]); for (var prop in Properties) { if (hasOwn.call(Properties, prop)) { obj[prop] = Properties[prop]; } } } // 5. Return obj return obj; }; })(); }
Спецификации
Спецификация | Статус | Комментарии |
---|---|---|
ECMAScript 5.1 (ECMA-262) Определение 'Object.create' в этой спецификации. |
Стандарт | Изначальное определение. Реализована в JavaScript 1.8.5. |
ECMAScript 2015 (6th Edition, ECMA-262) Определение 'Object.create' в этой спецификации. |
Стандарт |
Совместимость с браузерами
Возможность | Chrome | Firefox (Gecko) | Internet Explorer | Opera | Safari |
---|---|---|---|---|---|
Базовая поддержка | 5 | 4.0 (2) | 9 | 11.60 | 5 |
Возможность | Android | Chrome для Android | Firefox Mobile (Gecko) | IE Mobile | Opera Mobile | Safari Mobile |
---|---|---|---|---|---|---|
Базовая поддержка | (Да) | (Да) | 4.0 (2) | (Да) | 11.50 | (Да) |
На основе таблицы совместимости Kangax.
Смотрите также
Object.defineProperty()
Object.defineProperties()
Object.prototype.isPrototypeOf()
- Запись в блоге Джона Резига о getPrototypeOf()