aboutsummaryrefslogtreecommitdiff
path: root/files/ru/web/javascript/reference/global_objects/function/name/index.html
blob: 6beee2a14dc2d58f7a8b33ec0484aa649ce60f99 (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
---
title: Function.name
slug: Web/JavaScript/Reference/Global_Objects/Function/name
tags:
  - ECMAScript6
  - Function
  - JavaScript
  - Property
  - Reference
translation_of: Web/JavaScript/Reference/Global_Objects/Function/name
---
<p>{{JSRef}}</p>

<p>Read-only свойство <code><strong>name</strong></code> глобального объекта {{jsxref("Function")}} и его <a href="/ru/docs/Web/JavaScript/Reference/Global_Objects/Function#Function_instances">экземпляров</a> содержит название функции созданное во время определения функции или присваивания ссылки на функцию переменной, свойству, аргументу и т. п. Для анонимных функций это свойство может иметь значение <code>"anonymous"</code> или пустую строку  <code>""</code>.</p>

<p>{{EmbedInteractiveExample("pages/js/function-name.html")}}</p>

<p>Интерактивные примеры размещены в GitHub репозитории. Если вы хотите добавить свои примеры, то клонируйте <a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> и пришлите пул реквест.</p>

<p>{{js_property_attributes(0,0,1)}}<br>
  </p>

<div class="blockIndicator note">
<p>Заметьте, что в нестандартном, pre-ES2015 релизе <code>configurable</code> свойство было <code>false</code></p>
</div>

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

<h3 id="Имя_объявленной_функции">Имя объявленной функции</h3>

<p>Свойство <code>name</code> возвращает имя функции, либо пустую строку для анонимных функций:</p>

<pre class="brush: js">function doSomething() {}

alert(doSomething.name); // выведет "doSomething"
</pre>

<h3 id="Имя_функции-конструктора">Имя функции-конструктора</h3>

<p>Функции, созданные синтаксисом <code>new Function(...)</code> или просто <code>Function(...)</code> создают  {{jsxref("Function")}} и имеют name "anonymous":​​​</p>

<pre class="brush: js"><code>(new Function).name; // "anonymous"</code>
</pre>

<h3 id="Предполагаемые_имена_функций">Предполагаемые имена функций</h3>

<p>Переменные и методы могут предположить название анонимной функции из ее синтаксической позиции  (new in ECMAScript 2015).</p>

<pre class="brush: js">var f = function() {};
var object = {
  someMethod: function() {}
};

<code>console.log(f.name); // "f"
console.log(object.someMethod.name); // "someMethod"</code></pre>

<p>Вы можете определить функцию с именем в {{jsxref("Operators/Function", "function expression", "", 1)}}:</p>

<pre class="brush: js">var object = {
  someMethod: function object_someMethod() {}
};
console.log(object.someMethod.name); // выведет "object_someMethod"

try { object_someMethod } catch(e) { console.log(e); }
// ReferenceError: object_someMethod is not defined
</pre>

<p>Вы не можете изменить имя функции, это свойство только для чтения:</p>

<pre class="brush: js">var object = {
  // анонимная функция
  someMethod: function() {}
};

object.someMethod.name = 'otherMethod';
alert(object.someMethod.name); //someMethod

</pre>

<p>Для изменения name можно использовать {{jsxref("Object.defineProperty()")}}.</p>

<h3 id="Сокращенные_имена_методов">Сокращенные имена методов</h3>

<pre class="brush: js"><code>var o = {
  foo(){}
};
o.foo.name; // "foo";</code></pre>

<h3 id="Имена_функций_после_байндинга">Имена функций после байндинга</h3>

<p>{{jsxref("Function.bind()")}} производит функцию, получающую имя "bound  и название самой функции.</p>

<pre class="brush: js"><code>function foo() {};
foo.bind({}).name; // "bound foo"</code>
</pre>

<h3 id="Имена_функций_для_getters_и_setters">Имена функций для getters и setters</h3>

<p>Когда используются <code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get">get</a></code> и <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/set">set</a>, "get" и "set" появятся в имени функции.</p>

<pre><code>let o = {
  get foo(){},
  set foo(x){}
};

var descriptor = Object.getOwnPropertyDescriptor(o, "foo");
descriptor.get.name; // "get foo"
descriptor.set.name; // "set foo";</code></pre>

<h3 id="Имена_функций-классов">Имена функций-классов</h3>

<p>Можно использовать <code>obj.constructor.name</code> чтобы проверить "class" объекта (читайте предупреждение ниже):</p>

<pre><code>function Foo() {}  // ES2015 Syntax: class Foo {}

var fooInstance = new Foo();
console.log(fooInstance.constructor.name); // logs "Foo"</code>
</pre>

<div class="blockIndicator warning">
<p><strong>Warning:</strong> Интерпретатор объявит встроенное <code>Function.name</code> свойство только если функция не имеет своего собственного свойства <em>name</em> (см.  <a href="https://www.ecma-international.org/ecma-262/6.0/#sec-setfunctionname">9.2.11 of the ECMAScript2015 Language Specification</a>). Однако, в ES2015 статичные методы перезаписывают OwnProperty конструкторов класса-функции (ECMAScript2015, <a href="https://www.ecma-international.org/ecma-262/6.0/#sec-runtime-semantics-classdefinitionevaluation">14.5.14.21.b</a> + <a href="https://www.ecma-international.org/ecma-262/6.0/#sec-object-initializer-runtime-semantics-propertydefinitionevaluation">12.2.6.9</a>).</p>
</div>

<p>Таким образом, нельзя получить доступ к <code>name</code> любого класса со статичным свойством <code>name()​​​​​​:</code></p>

<pre class="brush: js"><code>class Foo {
  constructor() {}
  static name() {}
}
</code></pre>

<p>Со <code>static name()</code> методом <code>Foo.name</code> больше не содержит название класса, но отсылает к функции <code>name()</code>. Приведенное выше определение класса в ES2015 будет вести себя в Chrome и Firefx как в  ES5:</p>

<pre><code>function Foo() {}
Object.defineProperty(Foo, 'name', { writable: true });
Foo.name = function() {};</code></pre>

<p>Пытаясь получить доступ к <code>fooInstance</code> с помощью <code>fooInstance.constructor.name</code> не даст название класса, но выведет метод <code>name()</code>. Пример:</p>

<pre><code>let fooInstance = new Foo();
console.log(fooInstance.constructor.name); // logs function name()</code></pre>

<p>Из ES5 syntax примера также видно, что в Chrome или Firefox статичное определение <code>Foo.name</code> становится <em>записываемым (writable)</em>. Встроенное определение в отсутствии кастомного статичного метода<em>доступно только для чтения</em>:</p>

<pre><code>Foo.name = 'Hello';
console.log(Foo.name); // logs "Hello" if class Foo has a static name() property but "Foo" if not.</code></pre>

<p>Следовательно не ожидайте, что <code>Function.name</code> свойство будет всегда содержать имя класса.</p>

<h3 id="Имена_функций-символов">Имена функций-символов</h3>

<p>Если у {{jsxref("Symbol")}} объявляется имя, то название метода - это имя квадратных скобках.</p>

<pre class="brush: js"><code>let sym1 = Symbol("foo");
let sym2 = Symbol();
let o = {
  [sym1]: function(){},
  [sym2]: function(){}
};

o[sym1].name; // "[foo]"
o[sym2].name; // ""</code>
</pre>

<h2 id="JavaScript_минифицированный">JavaScript минифицированный</h2>

<div class="blockIndicator warning">
<p><strong>Warning:</strong> Будьте осторожны, используя <code>Function.name</code> и изменения source кода с помощью JavaScript compressors (minifiers) или обфускаторов. Эти инструменты часто используются, как встроенные в  JavaScript build pipeline, чтобы сократить размер билда перед деплоем в production. Такие трансформации часто изменяют имена функций.</p>
</div>

<p>Такой source code:</p>

<pre><code>function Foo() {};
let foo = new Foo();

if (foo.constructor.name === 'Foo') {
  console.log("'foo' is an instance of 'Foo'");
} else {
  console.log('Oops!');
}</code></pre>

<p>может быть сжат в:</p>

<pre><code>function a() {};
let b = new a();
if (b.constructor.name === 'Foo') {
  console.log("'foo' is an instance of 'Foo'");
} else {
  console.log('Oops!');
}</code></pre>

<p>В несжатой версии код выполняется ожидаемо <code>"'foo' is an instance of 'Foo'"</code>. В то время, как в сжатой версии он ведет себя иначе. Если вы полагаетесь на <code>Function.name</code>, как в примере, то убедитесь, что pipeline не меняет код или не ожидайте от функции определенного имени.</p>

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

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

<div class="hidden">
<p>The compatibility table on this page is generated from structured data. If you'd like to contribute to the data, please check out <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> and send us a pull request.</p>
</div>

<p>{{Compat("javascript.builtins.Function.name")}}</p>

<div id="compat-mobile"></div>