|
41 | 41 | - [详述](#详述) |
42 | 42 | - [延伸资料](#延伸资料) |
43 | 43 | + [箭头函数](#箭头函数) |
44 | | - - [简述](#简述) |
45 | | - - [详述](#详述) |
| 44 | + - [简述](#简述-1) |
| 45 | + - [详述](#详述-1) |
46 | 46 | * [简洁性](#简洁性) |
47 | 47 | * [*this* 关键字](#this-关键字) |
48 | | - - [延伸资料](#延伸资料) |
| 48 | + - [相关资料](#相关资料) |
49 | 49 |
|
50 | 50 | ## 正文 |
51 | 51 |
|
@@ -214,3 +214,160 @@ person = ["Nick"] // 提示错误,因为用 const 声明的变量不能被重 |
214 | 214 |
|
215 | 215 | - [How let and const are scoped in JavaScript - WesBos](http://wesbos.com/javascript-scoping/) |
216 | 216 | - [Temporal Dead Zone (TDZ) Demystified](http://jsrocks.org/2015/01/temporal-dead-zone-tdz-demystified) |
| 217 | + |
| 218 | +### <a name="arrow_func_concept"></a> 箭头函数 |
| 219 | + |
| 220 | +ES6 JS 的最新版本已经介绍了*箭头函数*, 箭头函数是以另一种方式声明和使用函数。以下是箭头函数带来的一些好处: |
| 221 | + |
| 222 | +- 更加简洁 |
| 223 | +- 从上下文获取*this* |
| 224 | +- 隐式的返回方式 |
| 225 | + |
| 226 | +#### 简述 |
| 227 | + |
| 228 | +- 简洁性和隐式的返回方式 |
| 229 | + |
| 230 | +```js |
| 231 | +function double(x) { return x * 2; } // 传统函数声明方式 |
| 232 | +console.log(double(2)) // 4 |
| 233 | +``` |
| 234 | + |
| 235 | +```js |
| 236 | +const double = x => x * 2; // 同样的函数,使用具有隐式返回方式的箭头函数来表示 |
| 237 | +console.log(double(2)) // 4 |
| 238 | +``` |
| 239 | +- *this* 关键字 |
| 240 | + |
| 241 | +在箭头函数中, *this*的值就等于函数所处的封闭的可执行上下文的*this*。简单来说,就是在箭头函数中,当你调用一个位于函数体内部的函数时,在内部函数中,你不需要使用"that = this" 这样的声明语句。 |
| 242 | + |
| 243 | +```js |
| 244 | +function myFunc() { |
| 245 | + this.myVar = 0; |
| 246 | + setTimeout(() => { |
| 247 | + this.myVar++; |
| 248 | + console.log(this.myVar) // 1 |
| 249 | + }, 0); |
| 250 | +} |
| 251 | +``` |
| 252 | + |
| 253 | +#### 详述 |
| 254 | + |
| 255 | +##### 简洁性 |
| 256 | + |
| 257 | +箭头函数从很多方面都比传统的函数简洁。案例如下: |
| 258 | + |
| 259 | +- 隐式返回 VS 显式返回 |
| 260 | + |
| 261 | +**显式返回** 指的是函数的返回语句使用了return 关键字 |
| 262 | + |
| 263 | +```js |
| 264 | + function double(x) { |
| 265 | + return x * 2; // 使用了*return*关键字,显式返回 x * 2 |
| 266 | + } |
| 267 | +``` |
| 268 | + |
| 269 | +传统函数总是伴随着显式返回。使用箭头函数,你可以使用*隐式返回*,即不需要在函数体内使用return关键字就可以返回值。 |
| 270 | + |
| 271 | +隐式返回需要将所需代码写在一条语句中。 |
| 272 | + |
| 273 | +```js |
| 274 | + const double = (x) => { |
| 275 | + return x * 2; // 显式返回 |
| 276 | + } |
| 277 | +``` |
| 278 | + |
| 279 | +鉴于只返回单值,我们可以使用隐式返回。 |
| 280 | + |
| 281 | +```js |
| 282 | + const double = (x) => x * 2; |
| 283 | +``` |
| 284 | + |
| 285 | +为实现隐式返回,我们只需要 **移除花括号** 和 **return** 关键字。之所以被称为*隐式*返回,是因为*return*关键字不存在的情况下,函数仍可返回 ```x * 2```。 |
| 286 | + |
| 287 | +> **注意:** 如果你的函数不是返回一个单值(伴有*连带值*),那么既不可以使用显式返回也不可以使用隐式返回。 |
| 288 | +
|
| 289 | +除此之外, 如果你想隐式返回一个*object* 则必须使用圆括号对其修饰, |
| 290 | + |
| 291 | +```js |
| 292 | +const getPerson = () => ({ name: "Nick", age: 24 }) |
| 293 | +console.log(getPerson()) // { name: "Nick", age: 24 } -- 箭头函数返回的对象 |
| 294 | +``` |
| 295 | + |
| 296 | +- 函数只有一个参数 |
| 297 | + |
| 298 | +如果你的箭头函数只有一个参数,你可以省略修饰参数的圆括号,重新观察上面的代码: |
| 299 | + |
| 300 | +```js |
| 301 | + const double = (x) => x * 2; // 箭头函数只有一个参数 |
| 302 | +``` |
| 303 | + |
| 304 | +参数外面的圆括号可以省略: |
| 305 | + |
| 306 | +```js |
| 307 | + const double = x => x * 2; // 箭头函数只有一个参数 |
| 308 | +``` |
| 309 | + |
| 310 | +- 函数无参数 |
| 311 | + |
| 312 | +当箭头函数无参数时,必须使用圆括号,否则会出现语法错误. |
| 313 | + |
| 314 | +```js |
| 315 | + () => { // 必须提供圆括号 |
| 316 | + const x = 2; |
| 317 | + return x; |
| 318 | + } |
| 319 | +``` |
| 320 | + |
| 321 | +```js |
| 322 | + => { // 无圆括号,错误! |
| 323 | + const x = 2; |
| 324 | + return x; |
| 325 | + } |
| 326 | +``` |
| 327 | + |
| 328 | +##### *this* 关键字 |
| 329 | + |
| 330 | +要理解箭头函数中this的微妙之处,你必须首先了解JavaScript中[this](#this_def) 的行为。 |
| 331 | + |
| 332 | +在箭头函数中, *this*的值就等于函数所处的封闭可执行上下文的*this*。这句话的意思就是箭头函数不创建一个新的*this*, 而是从其所处的上下文环境中获取。 |
| 333 | + |
| 334 | +没有箭头函数,如果你想要从*this*访问函数内部的函数中的一个变量,你必须使用*that = this*或者*self = this*这样的技巧。 |
| 335 | + |
| 336 | +例如, 使用位于myFunc内部的函数setTimeout: |
| 337 | + |
| 338 | +```js |
| 339 | +function myFunc() { |
| 340 | + this.myVar = 0; |
| 341 | + var that = this; // that = this |
| 342 | + setTimeout( |
| 343 | + function() { // 在函数的内部创建一个新的 |
| 344 | + that.myVar++; |
| 345 | + console.log(that.myVar) // 1 |
| 346 | + |
| 347 | + console.log(this.myVar) // 未定义 -- 请参照上面的函数this定义 |
| 348 | + }, |
| 349 | + 0 |
| 350 | + ); |
| 351 | +} |
| 352 | +``` |
| 353 | + |
| 354 | +但是一旦使用箭头函数, *this* 将从包含这个箭头函数的上下文中获取: |
| 355 | + |
| 356 | +```js |
| 357 | +function myFunc() { |
| 358 | + this.myVar = 0; |
| 359 | + setTimeout( |
| 360 | + () => { // 从上下文中获取this, 在这里就是 myFunc |
| 361 | + this.myVar++; |
| 362 | + console.log(this.myVar) // 1 |
| 363 | + }, |
| 364 | + 0 |
| 365 | + ); |
| 366 | +} |
| 367 | +``` |
| 368 | + |
| 369 | +#### 相关资料 |
| 370 | + |
| 371 | +- [Arrow functions introduction - WesBos](http://wesbos.com/arrow-functions/) |
| 372 | +- [JavaScript arrow function - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions) |
| 373 | +- [Arrow function and lexical *this*](https://hackernoon.com/javascript-es6-arrow-functions-and-lexical-this-f2a3e2a5e8c4) |
0 commit comments