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
|
---
title: 方法的定义
slug: Web/JavaScript/Reference/Functions/Method_definitions
tags:
- ECMAScript 2015
- Functions
- JavaScript
- Object
- 语法
translation_of: Web/JavaScript/Reference/Functions/Method_definitions
---
<div>{{JsSidebar("Functions")}}</div>
<p>从ECMAScript 2015开始,在对象初始器中引入了一种更简短定义方法的语法,这是一种把方法名直接赋给函数的简写方式。</p>
<div>{{EmbedInteractiveExample("pages/js/functions-definitions.html")}}</div>
<p class="hidden">这个交互式例子的源代码位于 GitHub 仓库中。如果你想对这个交互式的样例做出一些贡献,请克隆 <a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> 然后提一个 pull request 给我们。</p>
<h2 id="语法">语法</h2>
<pre class="syntaxbox">var obj = {
<var>property</var>( <var>parameters…</var> ) {},
*<var>generator</var>( <var>parameters…</var> ) {},
async property( <var>parameters…</var> ) {},
async* generator( <var>parameters…</var> ) {},
// with computed keys:
[property]( <var>parameters…</var> ) {},
*[generator]( <var>parameters…</var> ) {},
async [property]( <var>parameters…</var> ) {},
// compare getter/setter syntax:
get <var>property</var>() {},
set <var>property</var>(<var>value</var>) {}
};
</pre>
<h2 id="描述">描述</h2>
<p>该简写语法与ECMAScript 2015的<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>
<p>如下代码:</p>
<pre class="brush: js">var obj = {
foo: function() {
/* code */
},
bar: function() {
/* code */
}
};</pre>
<p>现可被简写为:</p>
<pre class="brush: js">var obj = {
foo() {
/* code */
},
bar() {
/* code */
}
};</pre>
<div class="note">
<p><strong>注意:</strong>简写语法使用命名函数而不是匿名函数(如…<code>foo: function() {}</code>…)。命名函数可以从函数体调用(这对匿名函数是不可能的,因为没有标识符可以引用)。详细信息,请参阅{{jsxref("Operators/function","function","#Examples")}}。</p>
</div>
<h3 id="生成器方法">生成器方法</h3>
<p><a href="/en-US/docs/Web/JavaScript/Reference/Statements/function*">生成器方法</a>也可以用这种简写语法定义。使用它们时,</p>
<ul>
<li>简写语法中的星号(*)必须出现在生成器名前,也就是说<code>* g(){}</code>可以正常工作,而<code>g *(){}</code>不行。</li>
<li>
<p>非生成器方法定义可能不包含<code>yield</code>关键字。这意味着<a href="/zh-CN/docs/Web/JavaScript/Reference/Statements/Legacy_generator_function">遗留的生成器函数</a>也不会工作,并且将抛出 {{jsxref("SyntaxError")}}。始终使用<code>yield</code>与星号(*)结合使用。</p>
</li>
</ul>
<pre class="brush: js;highlight[12]">// 用有属性名的语法定义方法(ES6之前):
var obj2 = {
g: function*() {
var index = 0;
while(true)
yield index++;
}
};
// 同一个方法,简写语法:
var obj2 = {
* g() {
var index = 0;
while(true)
yield index++;
}
};
var it = obj2.g();
console.log(it.next().value); // 0
console.log(it.next().value); // 1</pre>
<h3 id="Async_方法">Async 方法</h3>
<p>{{jsxref("Statements/async_function", "Async 方法", "", 1)}}也可以使用简写语法来定义。</p>
<pre class="brush: js">// 用有属性名的语法定义方法(ES6之前):
var obj3 = {
f: async function () {
await some_promise;
}
};
// 同一个方法,简写语法:
var obj3 = {
async f() {
await some_promise;
}
};</pre>
<h3 id="Async_生成器方法">Async 生成器方法</h3>
<p><a href="/en-US/docs/Web/JavaScript/Reference/Statements/function*">生成器方法</a>也能成为 {{jsxref("Statements/async_function", "async", "", 1)}}.</p>
<pre class="brush: js">var obj4 = {
f: async function* () {
yield 1;
yield 2;
yield 3;
}
};
// The same object using shorthand syntax
var obj4 = {
async* f() {
yield 1;
yield 2;<code>
yield 3;
}
};</code></pre>
<h3 id="方法定义不是构造函数">方法定义不是构造函数</h3>
<p>所有方法定义不是构造函数,如果您尝试实例化它们,将抛出{{jsxref("TypeError")}}。</p>
<pre class="brush: js example-bad">var obj = {
method() {}
};
new obj.method; // TypeError: obj.method is not a constructor
var obj = {
* g() {}
};
new obj.g; // TypeError: obj.g is not a constructor (changed in ES2016)
</pre>
<h2 id="示例">示例</h2>
<h3 id="简单示例">简单示例</h3>
<pre class="brush: js;highlight[3]">var obj = {
a : "foo",
b(){ return this.a; }
};
console.log(obj.b()); // "foo"
</pre>
<h3 id="计算的属性名">计算的属性名</h3>
<p>该简写语法还支持计算的属性名称作为方法名。</p>
<pre class="brush: js;highlight[4]">var bar = {
foo0: function() { return 0; },
foo1() { return 1; },
['foo' + 2]() { return 2; }
};
console.log(bar.foo0()); // 0
console.log(bar.foo1()); // 1
console.log(bar.foo2()); // 2</pre>
<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('ES2015', '#sec-method-definitions', 'Method definitions')}}</td>
<td>{{Spec2('ES2015')}}</td>
<td>Initial definition.</td>
</tr>
<tr>
<td>{{SpecName('ES2016', '#sec-method-definitions', 'Method definitions')}}</td>
<td>{{Spec2('ES2016')}}</td>
<td>Changed that generator methods should also not have a [[Construct]] trap and will throw when used with <code>new</code>.</td>
</tr>
<tr>
<td>{{SpecName('ESDraft', '#sec-method-definitions', 'Method definitions')}}</td>
<td>{{Spec2('ESDraft')}}</td>
<td></td>
</tr>
</tbody>
</table>
<h2 id="浏览器兼容">浏览器兼容</h2>
<p>{{Compat("javascript.functions.method_definitions")}}</p>
<h2 id="参见">参见</h2>
<ul>
<li><code><a href="/en-US/docs/Web/JavaScript/Reference/Functions/get">get</a></code></li>
<li><code><a href="/en-US/docs/Web/JavaScript/Reference/Functions/set">set</a></code></li>
<li><a href="/en-US/docs/Web/JavaScript/Reference/Lexical_grammar">Lexical grammar</a></li>
</ul>
|