diff options
Diffstat (limited to 'files/ru/web/javascript/reference/operators/object_initializer/index.html')
-rw-r--r-- | files/ru/web/javascript/reference/operators/object_initializer/index.html | 431 |
1 files changed, 431 insertions, 0 deletions
diff --git a/files/ru/web/javascript/reference/operators/object_initializer/index.html b/files/ru/web/javascript/reference/operators/object_initializer/index.html new file mode 100644 index 0000000000..c7172a0c03 --- /dev/null +++ b/files/ru/web/javascript/reference/operators/object_initializer/index.html @@ -0,0 +1,431 @@ +--- +title: Инициализация объектов +slug: Web/JavaScript/Reference/Operators/Object_initializer +translation_of: Web/JavaScript/Reference/Operators/Object_initializer +--- +<div>{{JsSidebar("Операторы")}}</div> + +<p>Объекты могут быть инициализированы с помощью <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object"><code>new Object()</code></a>,<code> <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create">Object.create()</a> </code>или <em>литеральной</em> (<em>инициирующей</em>) нотации. Инициализатор объекта это разделенный запятыми список ноль или более пар имен свойств и ассоциируемых с ними значений, заключенных в фигурные скобки (<code>{}</code>).</p> + +<h2 id="Синтаксис">Синтаксис</h2> + +<pre class="brush: js">var o = {}; +var o = {a: 'foo', b: 42, c: {}}; + +var a = 'foo', b = 42, c = {}; +var o = {a: a, b: b, c: c}; + +var o = { + <var>property: function </var>([<var>parameters</var>]) {}, + get <var>property</var>() {}, + set <var>property</var>(<var>value</var>) {} +}; +</pre> + +<h3 id="Новая_нотация_в_ECMAScript_2015">Новая нотация в ECMAScript 2015</h3> + +<p>Пожалуйста, просмотрите таблицу поддержки этих нотаций. В неподдерживаемом окружении, эти нотации приведут к синтаксической ошибке.</p> + +<pre class="brush: js">// Сокращение имен свойств (ES2015) +var a = 'foo', b = 42, c = {}; +var o = {a, b, c}; + +// Сокращение имен методов (ES2015) +var o = { + <var>property</var>([<var>parameters</var>]) {} +}; + +// Вычисление имен свойств (ES2015) +var prop = 'foo'; +var o = { + [prop]: 'hey', + ['b' + 'ar']: 'there' +};</pre> + +<h2 id="Описание">Описание</h2> + +<p>Инициализатор объекта это выражение, которое описывает инициализацию {{jsxref("Object")}}. Объекты состоят из <em>свойств</em>, которые используются для описания объекта. Значения свойств объектов могут содержать как {{Glossary("примитивные")}} типы данных, так и другие объекты.</p> + +<h3 id="Создание_объектов">Создание объектов</h3> + +<p>Пустой объект без свойств может быть создан следующим образом:</p> + +<pre class="brush: js">var object = {};</pre> + +<p>Однако, преимущество <em>литеральной</em> или <em>инициирующей</em> нотации это возможность быстро создавать объекты со свойствами внутри фигурных скобок. Создается простой список пар <code>ключ: значение</code>, разделенных запятой. Следующий код создает объект с тремя парами значений и ключи это <code>"foo"</code>, <code>"age"</code> и <code>"baz"</code>. Значения этих ключей строка <code>"bar"</code>, число <code>42</code> и другой объект.</p> + +<pre class="brush: js">var object = { + foo: 'bar', + age: 42, + baz: {myProp: 12} +}</pre> + +<h3 id="Доступность_свойств">Доступность свойств</h3> + +<p>После того, как создали объект, вы, вероятно, захотите прочитать или изменить его. Свойства объектов могут быть получены при помощи точечной нотации или квадратных скобок. Смотрите <a href="/en-US/docs/Web/JavaScript/Reference/Operators/Property_Accessors">property accessors</a> для детальной информации.</p> + +<pre class="brush: js">object.foo; // "bar" +object['age']; // 42 + +object.foo = 'baz'; +</pre> + +<h3 id="Определение_свойств">Определение свойств</h3> + +<p>Мы уже рассмотрели, как объявить свойства, используя синтаксис инициализации. Зачастую, в коде появляются свойства, которые вы захотите поместить в объект. Вы увидете следующий код:</p> + +<pre class="brush: js">var a = 'foo', + b = 42, + c = {}; + +var o = { + a: a, + b: b, + c: c +};</pre> + +<p>С ECMAScript 2015 появилась короткая нотация, способная достичь того же:</p> + +<pre class="brush: js">var a = 'foo', + b = 42, + c = {}; + +// Сокращение имен свойств (ES2015) +var o = {a, b, c}; + +// Иначе говоря, +console.log((o.a === {a}.a)); // true +</pre> + +<h4 id="Повторение_имен_свойств">Повторение имен свойств</h4> + +<p>Когда используются одинаковые имена свойств, второе свойство перезапишет первое.</p> + +<pre class="brush: js">var a = {x: 1, x: 2}; +console.log(a); // {x: 2} +</pre> + +<p>В строгом режиме ECMAScript 5, повторение имен свойств будет воспринято как {{jsxref("SyntaxError")}}. С введением вычисляемых имен свойств и появлением возможности создавать дубликаты во время выполнения кода, ECMAScript 2015 убрал это ограничение.</p> + +<pre class="brush: js">function haveES2015DuplicatePropertySemantics() { + 'use strict'; + try { + ({prop: 1, prop: 2}); + + // Не будет ошибки, повторение имен доступно в строгом режиме + return true; + } catch(e) { + // Будет ошибка, дубликаты запрещены в строгом режиме + return false; + } +}</pre> + +<h3 id="Описание_методов">Описание методов</h3> + +<p>Свойство объекта также может ссылаться на <a href="/en-US/docs/Web/JavaScript/Reference/Functions">function</a>, <a href="/en-US/docs/Web/JavaScript/Reference/Functions/get">getter</a> или <a href="/en-US/docs/Web/JavaScript/Reference/Functions/set">setter</a>.</p> + +<pre class="brush: js">var o = { + <var>property: function </var>([<var>parameters</var>]) {}, + get <var>property</var>() {}, + set <var>property</var>(<var>value</var>) {} +};</pre> + +<p>В ECMAScript 2015, доступна короткая нотация, поэтому слово "function" более не обязательно.</p> + +<pre class="brush: js">// Сокращение имен методов (ES2015) +var o = { + <var>property</var>([<var>parameters</var>]) {}, + *<var>generator</var>() {} +};</pre> + +<p>В ECMAScript 2015 есть способ кратко объявить свойства, чьими значениями являются генераторы функций:</p> + +<pre class="brush: js">var o = { + *<var>generator</var>() { + ........... + } +};</pre> + +<p>Что эквивалентно следующей ES5-подобной нотации (но отметьте, что ECMAScript 5 не содержит генераторов):</p> + +<pre class="brush: js">var o = { + generator<var>: function* </var>() { + ........... + } +};</pre> + +<p>Для большей информации и примеров смотри <a href="/en-US/docs/Web/JavaScript/Reference/Functions/Method_definitions">method definitions</a>.</p> + +<h3 id="Вычисляемые_имена_свойств">Вычисляемые имена свойств</h3> + +<p>Начиная с ECMAScript 2015, синтаксис объявления объектов также поддерживает вычисляемые имена свойств. Это позволяет добавлять в скобки <code>[] </code>выражение, которое будет вычислено, как имя свойства. Это похоже на скобочную нотацию синтаксиса <a href="/en-US/docs/Web/JavaScript/Reference/Operators/Property_Accessors">property accessor</a>, которую вы, вероятно, уже использовали, чтобы прочитать и задать свойство. Теперь можно использовать аналогичный способ с литеральными объектами:</p> + +<pre class="brush: js">// Вычисляемое имя свойства (ES2015) +var i = 0; +var a = { + ['foo' + ++i]: i, + ['foo' + ++i]: i, + ['foo' + ++i]: i +}; + +console.log(a.foo1); // 1 +console.log(a.foo2); // 2 +console.log(a.foo3); // 3 + +var param = 'size'; +var config = { + [param]: 12, + ['mobile' + param.charAt(0).toUpperCase() + param.slice(1)]: 4 +}; + +console.log(config); // {size: 12, mobileSize: 4}</pre> + +<h3 id="Spread-свойства">Spread-свойства</h3> + +<p><a href="https://github.com/tc39/proposal-object-rest-spread">Rest/Spread свойство ECMAScript</a> предлагает (stage 3) добавлять <a href="/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator">spread</a> свойства в литеральную нотацию. Оно копирует собственные перечисляемые свойства из представленного объекта в новый.</p> + +<p>Поверхностное копирование (исключая prototype) или слияние объектов теперь возможно с помощью более короткого синтаксиса, чем {{jsxref("Object.assign()")}}.</p> + +<pre class="brush: js">var obj1 = { foo: 'bar', x: 42 }; +var obj2 = { foo: 'baz', y: 13 }; + +var clonedObj = { ...obj1 }; +// Объект { foo: "bar", x: 42 } + +var mergedObj = { ...obj1, ...obj2 }; +// Объект { foo: "baz", x: 42, y: 13 }</pre> + +<p>Заметьте, что {{jsxref("Object.assign()")}} вызывает <a href="/en-US/docs/Web/JavaScript/Reference/Functions/set">setters</a>, тогда как оператор spread нет.</p> + +<h3 id="Изменение_Prototype">Изменение Prototype</h3> + +<p>Объявление свойства в виде <code>__proto__: value</code> или <code>"__proto__": value</code> не создаст свойства с именем <code>__proto__</code>. Вместо этого, если предоставляемое значение объект или <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/null"><code>null</code></a>, оно заменит <code>[[Prototype]]</code> создаваемого объекта на это значение. (Если значение не объект или null, объект не изменится.)</p> + +<pre class="brush: js">var obj1 = {}; +assert(Object.getPrototypeOf(obj1) === Object.prototype); + +var obj2 = {__proto__: null}; +assert(Object.getPrototypeOf(obj2) === null); + +var protoObj = {}; +var obj3 = {'__proto__': protoObj}; +assert(Object.getPrototypeOf(obj3) === protoObj); + +var obj4 = {__proto__: 'not an object or null'}; +assert(Object.getPrototypeOf(obj4) === Object.prototype); +assert(!obj4.hasOwnProperty('__proto__')); +</pre> + +<p>Только одно изменение prototype разрешено через литеральное объявление объекта: несколько изменений prototype вызовут синтаксическую ошибку.</p> + +<p>Объявление свойства не через "двоеточие" не изменит знаения prototype: это описание будет выглядеть идентично такому же объявлению свойства с использованием любого другого имени.</p> + +<pre class="brush: js">var __proto__ = 'variable'; + +var obj1 = {__proto__}; +assert(Object.getPrototypeOf(obj1) === Object.prototype); +assert(obj1.hasOwnProperty('__proto__')); +assert(obj1.__proto__ === 'variable'); + +var obj2 = {__proto__() { return 'hello'; }}; +assert(obj2.__proto__() === 'hello'); + +var obj3 = {['__prot' + 'o__']: 17}; +assert(obj3.__proto__ === 17); +</pre> + +<h2 id="Литеральная_нотация_vs_JSON">Литеральная нотация vs JSON</h2> + +<p>Литеральная нотация не то же самое, что и <strong>J</strong>ava<strong>S</strong>cript <strong>O</strong>bject <strong>N</strong>otation (<a href="/en-US/docs/Glossary/JSON">JSON</a>). Хотя они и выглядят аналогично, существует разница между ними:</p> + +<ul> + <li>JSON позволяет объявление свойств <em>только</em> с помощью синтаксиса <code>"property": value</code>. Имя свойства должно быть заключено в двойные кавычки и объявление не может быть сокращено.</li> + <li>В JSON значения могут быть только строками, числами, массивами, <code>true</code>, <code>false</code>, <code>null</code> или другими (JSON) объектами.</li> + <li>Значения-функции (смотри "Методы" выше) не могут быть присвоены свойствам в JSON.</li> + <li>Объект вида {{jsxref("Date")}} будет строкой после {{jsxref("JSON.parse()")}}.</li> + <li>{{jsxref("JSON.parse()")}} отклонит вычисляемые имена свойств и вернет ошибку.</li> +</ul> + +<h2 id="Спецификации">Спецификации</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Specification</th> + <th scope="col">Status</th> + <th scope="col">Comment</th> + </tr> + <tr> + <td>{{SpecName('ES1')}}</td> + <td>{{Spec2('ES1')}}</td> + <td>initial definition.</td> + </tr> + <tr> + <td>{{SpecName('ES5.1', '#sec-11.1.5', 'Object Initializer')}}</td> + <td>{{Spec2('ES5.1')}}</td> + <td><a href="/en-US/docs/Web/JavaScript/Reference/Functions/get">getter</a> and <a href="/en-US/docs/Web/JavaScript/Reference/Functions/set">setter</a> added.</td> + </tr> + <tr> + <td>{{SpecName('ES2015', '#sec-object-initializer', 'Object Initializer')}}</td> + <td>{{Spec2('ES2015')}}</td> + <td>Shorthand method/property names and computed property names added.</td> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-object-initializer', 'Object Initializer')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td></td> + </tr> + <tr> + <td><a href="https://github.com/tc39/proposal-object-rest-spread">Rest/Spread Properties for ECMAScript </a></td> + <td>Draft</td> + <td>Stage 3 draft.</td> + </tr> + </tbody> +</table> + +<h2 id="Поддержка_браузерами">Поддержка браузерами</h2> + +<div>{{CompatibilityTable}}</div> + +<div id="compat-desktop"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Chrome</th> + <th>Edge</th> + <th>Firefox (Gecko)</th> + <th>Internet Explorer</th> + <th>Opera</th> + <th>Safari</th> + </tr> + <tr> + <td>Basic support</td> + <td>{{CompatChrome(1.0)}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatGeckoDesktop("1.0")}}</td> + <td>1</td> + <td>1</td> + <td>1</td> + </tr> + <tr> + <td>Computed property names</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatGeckoDesktop("34")}}</td> + <td>{{CompatNo}}</td> + <td>34</td> + <td>7.1</td> + </tr> + <tr> + <td>Shorthand property names</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatGeckoDesktop("33")}}</td> + <td>{{CompatNo}}</td> + <td>34</td> + <td>9</td> + </tr> + <tr> + <td>Shorthand method names</td> + <td>{{CompatChrome(42.0)}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatGeckoDesktop("34")}}</td> + <td>{{CompatNo}}</td> + <td>34</td> + <td>9</td> + </tr> + <tr> + <td>Spread properties</td> + <td>{{CompatChrome(60)}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatGeckoDesktop("55")}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + </tr> + </tbody> +</table> +</div> + +<div id="compat-mobile"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Android</th> + <th>Android Webview</th> + <th>Edge</th> + <th>Firefox Mobile (Gecko)</th> + <th>IE Mobile</th> + <th>Opera Mobile</th> + <th>Safari Mobile</th> + <th>Chrome for Android</th> + </tr> + <tr> + <td>Basic support</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatGeckoMobile("1.0")}}</td> + <td>1</td> + <td>1</td> + <td>1</td> + <td>{{CompatChrome(1.0)}}</td> + </tr> + <tr> + <td>Computed property names</td> + <td>{{CompatNo}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatGeckoMobile("34")}}</td> + <td>{{CompatNo}}</td> + <td>34</td> + <td>7.1</td> + <td>{{CompatNo}}</td> + </tr> + <tr> + <td>Shorthand property names</td> + <td>{{CompatNo}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatGeckoMobile("33")}}</td> + <td>{{CompatNo}}</td> + <td>34</td> + <td>9</td> + <td>{{CompatNo}}</td> + </tr> + <tr> + <td>Shorthand method names</td> + <td>{{CompatNo}}</td> + <td>{{CompatChrome(42.0)}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatGeckoMobile("34")}}</td> + <td>{{CompatNo}}</td> + <td>34</td> + <td>9</td> + <td>{{CompatChrome(42.0)}}</td> + </tr> + <tr> + <td>Spread properties</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatGeckoMobile("55")}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + </tr> + </tbody> +</table> +</div> + +<h2 id="See_also">See also</h2> + +<ul> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Property_Accessors">Property accessors</a></li> + <li><code><a href="/en-US/docs/Web/JavaScript/Reference/Functions/get">get</a></code> / <code><a href="/en-US/docs/Web/JavaScript/Reference/Functions/set">set</a></code></li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Functions/Method_definitions">Method definitions</a></li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Lexical_grammar">Lexical grammar</a></li> +</ul> |