aboutsummaryrefslogtreecommitdiff
path: root/files/ru/web/javascript/reference/global_objects/object/create/index.html
blob: f7b4d2c69baba5732293370a0dbb27c4b14cb374 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
---
title: Object.create()
slug: Web/JavaScript/Reference/Global_Objects/Object/create
tags:
  - ECMAScript5
  - JavaScript
  - Method
  - Object
  - Reference
  - Référence(2)
  - polyfill
translation_of: Web/JavaScript/Reference/Global_Objects/Object/create
---
<div>{{JSRef}}</div>

<p>Метод <code><strong>Object.create()</strong></code> создаёт новый объект с указанным прототипом и свойствами.</p>

<h2 id="Syntax">Синтаксис</h2>

<pre class="syntaxbox notranslate"><code>Object.create(<var>proto</var>[, <var>propertiesObject</var>])</code></pre>

<h3 id="Parameters">Параметры</h3>

<dl>
 <dt><code>proto</code></dt>
 <dd>Объект, который станет прототипом вновь созданного объекта.</dd>
 <dt><code>propertiesObject</code></dt>
 <dd>Необязательный параметр. Если указан и не равен {{jsxref("Global_Objects/undefined", "undefined")}}, должен быть объектом, чьи собственные перечисляемые свойства (то есть такие, которые определены на самом объекте, а не унаследованы по цепочке прототипов) указывают дескрипторы свойств, добавляемых в новый объект. Имена добавляемых свойств совпадают с именами свойств в этом объекте. Эти свойства соответствуют второму аргументу метода {{jsxref("Object.defineProperties()")}}.</dd>
</dl>

<h3 id="Возвращаемые_значения">Возвращаемые значения</h3>

<p>Новый объект с заданным прототипом и свойствами</p>

<h3 id="Throws">Выбрасываемые исключения</h3>

<p>Выбрасывает исключение {{jsxref("Global_Objects/TypeError", "TypeError")}}, если параметр <code>proto</code> не является {{jsxref("Global_Objects/null", "null")}} или объектом (исключение составляют объекты-обёртки примитивных типов).</p>

<h2 id="Examples">Примеры</h2>

<h3 id="Example.3A_Classical_inheritance_with_Object.create">Пример: классическое наследование с <code>Object.create()</code></h3>

<p>Ниже показан пример использования <code>Object.create()</code> для имитации классического наследования. Это пример одиночного наследования, поскольку только его поддерживает JavaScript.</p>

<pre class="brush: js notranslate">// 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); // выведет 'Фигура переместилась.'
</pre>

<p>Если вы хотите наследоваться от нескольких объектов, то это возможно сделать при помощи примесей.</p>

<pre class="brush: js notranslate">function MyClass() {
  SuperClass.call(this);
  OtherSuperClass.call(this);
}

MyClass.prototype = Object.create(SuperClass.prototype); // наследование
mixin(MyClass.prototype, OtherSuperClass.prototype); // примешивание

MyClass.prototype.myMethod = function() {
  // что-то делаем
};
</pre>

<p>Функция примешивания должна копировать функции из прототипа суперкласса в прототип подкласса, она должна предоставляться пользователем. Примером примеси может служить функция <a href="http://api.jquery.com/jQuery.extend/">jQuery.extend()</a>.</p>

<h3 id="Example.3A_Using_propertiesObject_argument_with_Object.create">Пример: использование аргумента <code>propertiesObject</code> с <code>Object.create()</code></h3>

<pre class="brush: js notranslate">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
  }
});
</pre>

<h2 id="Polyfill">Полифил</h2>

<p>Для этого полифила необходима правильно работающая Object.prototype.hasOwnProperty.</p>

<pre class="brush: js notranslate">if (typeof Object.create != 'function') {
  // Этапы производства ECMA-262, издание 5, 15.2.3.5
  // Ссылка: http://es5.github.io/#x15.2.3.5
  Object.create = (function() {
    // Чтобы сэкономить память, используйте общий конструктор
    function Temp() {}

    // делает безопасную ссылку на Object.prototype.hasOwnProperty
    var hasOwn = Object.prototype.hasOwnProperty;

    return function (O) {
      // 1. Если Type(O) не является Object or Null выдаётся исключение TypeError.
      if (typeof O != 'object') {
        throw TypeError('Object prototype may only be an Object or null');
      }

      // 2. Пусть obj будет результатом создания нового объекта, как если бы
      //    выражение new Object(), где Object является стандартным встроенным
      //    конструктором  с таким именем
      // 3. Установите для внутреннего свойства [[Prototype]] объекта obj значение O.
      Temp.prototype = O;
      var obj = new Temp();
      Temp.prototype = null; // Давайте не будем держать случайные ссылки на О...

      // 4.  Если аргумент Properties присутствует и не определён, добавляем
      //    собственные свойства к obj, как будто вызывая стандартную встроенную
      //    функцию Object.defineProperties с аргументами obj и
      //    Properties.
      if (arguments.length &gt; 1) {
        // Object.defineProperties делает ToObject своим первым аргументом.
        var Properties = Object(arguments[1]);
        for (var prop in Properties) {
          if (hasOwn.call(Properties, prop)) {
            obj[prop] = Properties[prop];
          }
        }
      }

      // 5. Возвращает obj
      return obj;
    };
  })();
}
</pre>

<h2 id="Specifications">Спецификации</h2>

<table class="standard-table">
 <tbody>
  <tr>
   <th scope="col">Спецификация</th>
   <th scope="col">Статус</th>
   <th scope="col">Комментарии</th>
  </tr>
  <tr>
   <td>{{SpecName('ES5.1', '#sec-15.2.3.5', 'Object.create')}}</td>
   <td>{{Spec2('ES5.1')}}</td>
   <td>Изначальное определение. Реализована в JavaScript 1.8.5.</td>
  </tr>
  <tr>
   <td>{{SpecName('ES6', '#sec-object.create', 'Object.create')}}</td>
   <td>{{Spec2('ES6')}}</td>
   <td></td>
  </tr>
 </tbody>
</table>

<h2 id="Browser_compatibility">Совместимость с браузерами</h2>

<div>{{Compat("javascript.builtins.Object.create")}}</div>

<h2 id="See_also">Смотрите также</h2>

<ul>
 <li>{{jsxref("Object.defineProperty()")}}</li>
 <li>{{jsxref("Object.defineProperties()")}}</li>
 <li>{{jsxref("Object.prototype.isPrototypeOf()")}}</li>
 <li>Запись в блоге Джона Резига о <a href="http://ejohn.org/blog/objectgetprototypeof/">getPrototypeOf()</a></li>
</ul>