当前位置:   article > 正文

ES6新特性2:箭头函数_es6箭头函数

es6箭头函数

更多精彩访问http://www.kongzid.com/archives/es2

欢迎阅读《ES6新特性系列》

ES6标准新增了一种新的函数:Arrow Function(箭头函数),允许使用箭头 =>定义函数。相对于普通函数,在语法上类似于C#,Java 8中的相关功能,支持表达式和语句体。与普通函数不同,箭头函数与this周围的代码拥有相同的作用域。箭头函数有以下特征:1、不需要 function 关键字来创建函数。2、省略 return 关键字。3、this始终指向函数申明时所在作用域下的this值(即箭头函数里面根本没有自己的this,而是引用外层的this)。

使用ES6箭头函数语法定义函数,将原函数的“function”关键字和函数名都删掉,并使用“=>”连接参数列表和函数体。

箭头函数的作用

  1. // 1、使表达更加简洁
  2. const isEven = n => n % 2 === 0;
  3. const square = n => n * n;
  4. // 2、简化回调函数
  5. // 普通函数写法
  6. [1,2,3].map(function (x) {
  7. return x * x;
  8. });
  9. // 箭头函数写法
  10. [1,2,3].map(x => x * x);

1、无参数箭头函数

  1. // es5 写法
  2. var fun = function() {
  3. }
  4. // es6 箭头函数写法
  5. // 没有参数时,需要用()进行占位,代表参数部分
  6. var fn = () => {
  7. }
  8. // 以上2种写法是等价的。

2、1个参数箭头函数

当函数参数只有一个,括号可以省略;但是没有参数时,括号不可以省略。

  1. let print = function (obj){
  2. console.log(obj);
  3. }
  4. // 简写为:
  5. let print2 = obj => console.log(obj);

3、多个参数箭头函数

  1. let sum = function(a,b){
  2. return a + b;
  3. }
  4. // 简写为:
  5. let sum2 = (a,b) => a + b;
  6. // 也可以简写为:
  7. let sum3 = (a,b) => { return a + b; }

4、可变参数箭头函数

  1. var fn = function(a, b, ...args) {
  2. }
  3. // 简写为:
  4. var fn = (a, b, ...args) => {
  5. }

5、当有多行代码时,可以使用{ }括起来函数体

函数体如果只包含一个表达式,可以省略{ ... }和return。若包含多条语句,这时候就不能省略{ ... }和return。

  1. let sum3 = (a.b) =>{
  2. return a+b;
  3. }
  4. let hello3 = () =>{
  5. console.log("Hello");
  6. console.log("World");
  7. };
  8. hello3();

6、对象参数和返回值

  1. // 注意,用小括号包含大括号则是对象的定义,而非函数主体
  2. x => {key: x} // 报错
  3. x => ({key: x}) // 正确
  4. // 如果箭头函数直接返回一个对象,必须在对象外面加上括号,否则会报错。
  5. // 报错
  6. let getTempItem = id => { id: id, name: "Temp" };
  7. // 不报错
  8. let getTempItem = id => ({ id: id, name: "Temp" });
  9. // 如果箭头函数只有一行语句,且不需要返回值,可以采用下面的写法,就不用写大括号了。
  10. let fn = () => void doesNotReturn();

6、函数默认值

  1. // ES6 之前,无法给一个函数参数设置默认值,只能采用变通写法:
  2. function add(a,b){ // 如果没有给参数b传值,则b=1
  3. b = b || 1;
  4. return a+b;
  5. }
  6. console.log(add(10)); //输出11
  7. console.log(add(1020)); //输出30
  8. // ES6之后
  9. function add(a,b = 1){
  10. return a+b;
  11. }
  12. console.log(add(10)); //输出11
  13. console.log(add(1020)); //输出30

7、对象的函数属性简写

  1. let person = {
  2. name: "Tom",
  3. // ES6之前
  4. eat: function (food){
  5. console.log(this.name + "在吃" + food);
  6. }
  7. // 箭头函数写法
  8. eat2: food => console.log(person.name + "在吃" + food);
  9. // 简写版
  10. eat3(food){
  11. console.log(this.name + "在吃" + food);
  12. }
  13. }

8、箭头函数结合解构表达式

  1. const person = {
  2. name: "Tom",
  3. age: 20,
  4. language: ["Java","Python","JS"]
  5. }
  6. // 普通写法
  7. function hello(person){
  8. console.log("Hello," + person.name);
  9. }
  10. // 以下是使用箭头函数和解构表达式的写法
  11. var hi = ({name}) => console.log("hello," + name);
  12. hi(person);

9、箭头函数this

对于普通函数来说,内部的this指向函数运行时所在的对象,但是这一点对箭头函数不成立。它没有自己的this对象,内部的this就是定义时上层作用域中的this。也就是说,箭头函数内部的this指向是固定的,相比之下,普通函数的this指向是可变的。

  1. function foo() {
  2. setTimeout(() => {
  3. console.log('id:', this.id);
  4. }, 100);
  5. }
  6. var id = 21;
  7. foo.call({ id: 42 });
  8. // id: 42

上例中setTimeout()的参数是一个箭头函数,这个箭头函数的定义生效是在foo函数生成时,而它的真正执行要等到 100 毫秒后。如果是普通函数,执行时this应该指向全局对象window,这时应该输出21。但是,箭头函数导致this总是指向函数定义生效时所在的对象(本例是{id: 42}),所以打印出来的是42。

  1. function Timer() {
  2. this.s1 = 0;
  3. this.s2 = 0;
  4. // 箭头函数
  5. setInterval(() => this.s1++, 1000);
  6. // 普通函数
  7. setInterval(function () {
  8. this.s2++;
  9. }, 1000);
  10. }
  11. var timer = new Timer();
  12. setTimeout(() => console.log('s1: ', timer.s1), 3100);
  13. setTimeout(() => console.log('s2: ', timer.s2), 3100);
  14. // s1: 3
  15. // s2: 0

上面代码中,Timer函数内部设置了两个定时器,分别使用了箭头函数和普通函数。前者的this绑定定义时所在的作用域(即Timer函数),后者的this指向运行时所在的作用域(即全局对象)。所以,3100 毫秒之后,timer.s1被更新了 3 次,而timer.s2一次都没更新。

箭头函数实际上可以让this指向固定化,绑定this使得它不再可变,这种特性很有利于封装回调函数。下面是一个例子,DOM 事件的回调函数封装在一个对象里面。

  1. var handler = {
  2. id: '123456',
  3. init: function() {
  4. document.addEventListener('click',
  5. event => this.doSomething(event.type), false);
  6. },
  7. doSomething: function(type) {
  8. console.log('Handling ' + type + ' for ' + this.id);
  9. }
  10. };

上面代码的init()方法中,使用了箭头函数,这导致这个箭头函数里面的this,总是指向handler对象。如果回调函数是普通函数,那么运行this.doSomething()这一行会报错,因为此时this指向document对象。

总之,箭头函数根本没有自己的this,导致内部的this就是外层代码块的this。正是因为它没有this,所以也就不能用作构造函数。

继续阅读《ES6新特性3:变量的解构赋值》

上一篇《ES6新特性1:let 和 const 命令》

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/115809?site
推荐阅读
相关标签
  

闽ICP备14008679号