ES6学习02 箭头函数

1.基本用法

1.1定义箭头函数

ES6允许了用“箭头”(=>)来定义函数

var f = v => v;

// 等同于
var f = function (v) {
  return v;
};

当函数没有参数或者有多个参数(多于一个)时,需要用括号包裹参数部分

var f = () => 5;
// 等同于
var f = function () { return 5 };

var sum = (num1, num2) => num1 + num2;
// 等同于
var sum = function(num1, num2) {
  return num1 + num2;
};

当箭头函数的代码块多于一条语句时,就需要使用大括号括起来,并且用return返回。

var sum = (num1, num2) => { return num1 + num2; }

当箭头函数返回对象时,需要在对象外面加上一个括号,否则报错。

// 未加括号:报错
let getTempItem = id => { id: id, name: "Temp" };

// 加括号:不报错
let getTempItem = id => ({ id: id, name: "Temp" });

有些特殊情况不加括号也可以运行,但为了避免一些不必要的麻烦,建议大家还是在返回对象时加上括号。

2.箭头函数简化代码

2.1.在一些场景下,表达更加简洁

const isEven = n => n % 2 === 0;
const square = n => n * n;

显而易见,上面的两个函数用两行就可以定义,而且看起来更加简洁。若是不用工具函数则会占用多行,相对箭头函数来说,阅读起来也会没那么方便。

2.2.简化回调函数

[1,2,3].map(function (x) {
  return x * x;
});

// 箭头函数写法
[1,2,3].map(x => x * x);

上面函数调用的map方法使用了箭头函数,更加简洁了

Array.map( function ( ) { } );
JS map方法 返回一个新Array1
Array使用了括号中的回调后返回Array1
上面的函数打印为 // [1,4,9]

另一个例子

// 正常函数写法
var result = values.sort(function (a, b) {
  return a - b;
});

// 箭头函数写法
var result = values.sort((a, b) => a - b);

Array.sort(function)方法:排序(比较字母),可以插入函数比较
sort方法直接修改数组,不会返回新数组。

3.箭头函数this指向

3.1.内部不存在this

箭头函数内部其实并不存在this,每当在箭头函数中使用this时,因为箭头函数中没有this,所以会带着这个this向上找。

所以通俗的说箭头函数中的this等于是在函数外部var了一个变量缓存了this,并在函数中调用,这也是我们用普通函数经常会用到的方法,而箭头函数则更加方便。

注:由于箭头函数没有自己的this,所以当然也就不能用call()、apply()、bind()这些方法去改变this的指向。

3.2.this指向固定

在普通函数中,this的指向,是指向运行时的作用域,等于说在普通函数中this的指向可以随着函数运行时作用域的不同而可能产生不同的指向。
而箭头函数的this的指向,是在指向定义时的作用域,并且不会改变

下面来看几个例子

function foo() {
  setTimeout(() => {
    console.log('id:', this.id);
  }, 100);
}

var id = 21;

foo.call({ id: 42 });
// id: 42

上面在定义函数时,用了call方法将foo函数的 this 指向 { id:2 },setTimeout中又是用的箭头函数,当使用this时,向上找到foo函数的this,于是输出id:42

若setTimeout使用的普通函数function,使用 this时将直接指向全局
注:call使用后会直接执行函数,所以才能打印出参数`

function Timer() {
  this.s1 = 0;
  this.s2 = 0;
  // 箭头函数
  setInterval(() => this.s1++, 1000); // 执行时,向上层寻找 this,上一层的this指向实例化Timer()函数的对象。
  // 普通函数
  setInterval(function () { // 此普通函数执行时的 this 指向全局。
    this.s2++;
  }, 1000);
}

var timer = new Timer();

setTimeout(() => console.log('s1: ', timer.s1), 3100);  //s1: 3 
setTimeout(() => console.log('s2: ', timer.s2), 3100);  //s2:0
setTimeout(() => console.log('window.s2: ', s2), 3100); //window.s2:NaN

上面的代码与之前的例子同理,大家可以自己琢磨一下。

不过在此段代码最后发现了一个现象比较疑惑,使用普通函数 this.s2++
后,打印这个全局的s2并没有报错,而是NaN,后来请教了群里的大佬,了解到了为何不报错,因为普通函数中的,this指向了window,而window又是对象,所以打印出来为NaN或是undefind。 不懂得可以自己试一试

3.3.在函数中不存在的变量

刚刚重点描述了this在箭头函数中不存在,还有几个变量在箭头函数中也是不存在的

> arguments 、super 、new.target
如果在箭头函数中使用,同 this 一样,也会向上找所对应的变量。

function foo() {
  setTimeout(() => {
    console.log('args:', arguments);
  }, 100);
}

foo(2, 4, 6, 8)
// args: [2, 4, 6, 8]

上面代码中,箭头函数内部的变量arguments,其实是函数foo的arguments变量。

4.箭头函数不适用的场合

4.1.当使用箭头函数定义对象的方法时,且该方法内部包括this。

var a=3;
var object = { 
    a:2, 
    run: () => {this.a}      //a=3;
    }; 
object.run(); 

为什么上面的 this.a 会输出3呢?
之前的知识点有提到过,箭头函数中是没有this的。JS执行时发现run()中没有this,于是它向上找,它的上一层为object,而object的this指向window,所以代码中的this.a 等同于 window.a

4.2.当需要动态this的时候,也不应使用箭头函数。

var button = document.getElementById('press');
button.addEventListener('click', () => {
  this.classList.toggle('on');
});

上面代码运行时,点击按钮会报错,因为button的监听函数是一个箭头函数,导致里面的this就是全局对象。如果改成普通函数,this就会动态指向被点击的按钮对象。

4.3当函数体比较复杂时

当函数体比较复杂,或是函数内部代码中有很多读写操作,这时也不应该用箭头函数。这时选择使用普通函数可以提高代码可读性

5.箭头函数使用注意事项

  1. 箭头函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。因此函数的this是静态的(固定不变的)
  2. 箭头函数不可以被实例化,也是就是说,不可以使用new来构造函数实例化对象(主要原因是因为箭头函数中没有this)
  3. 不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。

6.总结、

箭头函数是使用 ( ) => { } 来定义函数。括号中若是只有一个参数,则可以省略小括号。
箭头函数返回对象时,需要用小括号包裹代码块
箭头函数的优势
1.在定义相对简单的方法功能以及回调时,用箭头函数更加简洁,并且增加了可读性
2.箭头函数可以让this固定化 ,非常有利于封装回调
3.函数本身更加简洁
箭头函数的缺点
已在 4.箭头函数不适用的场合 中解释

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值