ES6 — 箭头函数
一 为什么要有箭头函数
我们在日常开发中,可能会需要写类似下面的代码
const Person = {
'name': 'little bear',
'age': 18,
'sayHello': function () {
setInterval(function () {
console.log('我叫' + this.name + '我今年' + this.age + '岁!')
}, 1000)
}
}
Person.sayHello()
上例的输出结果是什么呢?可能对javascript特性不是很熟悉的同学(我自己也是)会认为输出当然是
我叫little bear,今年18岁咯。如果你的答案是这个的话,那么我要恭喜你,答错了。其实上例的输出结果是我叫undefined,今年我undefined岁。为什么会输出这种结果呢?
这是因为setInterval执行的时候,是在全局作用域下的,所有this指向的是全局window,而window上没有name和age,所以当然输出的是undefined咯。不明白的同学可以去看看this的工作原理this。
那么,我们怎么要解决这个问题呢?
通常的写法是缓存this,然后在setInterval中用缓存的this进行操作,如下
const Person = {
'name': 'little bear',
'age': 18,
'sayHello': function () {
let self = this
setInterval(function () {
console.log('我叫' + self.name + '我今年' + self.age + '岁!')
}, 1000)
}
}
const sayHelloFun = Person.sayHello
sayHelloFun()
使用上叙方法,输出的结果就是大家所期待的我叫little bear,我今年18岁了。
那么,大家可能会觉得这样不科学,明明是写在对象里面的方法,为什么还要使用缓存这个对象才能正确使用。ECMA组织觉得这确实是个问题,之后在es6的新特性里添加了箭头函数,它能很好的解决这个问题。另外箭头函数还用简化代码量的特点。
二 什么是箭头函数
箭头函数的语法非常简单,看一下最简单的箭头函数表示法
() => console.log('Hello')
之前没有接触过箭头函数的人可能会惊讶于其代码的简洁。对比之前如果要写一个这样的函数
function(){
console.log('hello')
}
箭头函数的简洁性一目了然。
更多关于箭头函数语法可点击箭头函数语法
三 和普通函数的区别
从上面的例子中,我们已经可以看出箭头函数的优势。
和普通函数相比,箭头函数主要就是以下两个方面的特点
- 不绑定this,arguments
- 更简化的代码语法
第二个特点不需要过多赘述,下面我们来看看不绑定this和arguments这两个特点
3.1 不绑定this
什么叫不绑定this,我个人的理解为箭头函数的this其实就是在定义的时候就确定好的,以后不管怎么调用这个箭头函数,箭头函数的this始终为定义时的this
我们还是以前面的那个setInterval代码为例
const Person = {
'name': 'little bear',
'age': 18,
'sayHello': function () {
setInterval(function () {
console.log('我叫' + this.name + '我今年' + this.age + '岁!')
}, 1000)
}
Person.sayHello()
当Person.sayHello()去执行setInterval的时候,是在全局作用下执行的所有setInterval回调函数的this就为全局对象。es3-5中的函数this的值和调用这个函数的上下文有关。(注意是调用)
我们用箭头函数重写上诉函数
const Person = {
'name': 'little bear',
'age': 18,
'sayHello': () => {
setInterval(() => {
console.log('我叫' + this.name + '我今年' + this.age + '岁!')
}, 1000)
}
Person.sayHello()
大家猜猜结果是什么???
输出的是我叫'little bear',今年18岁嘛?
哈哈,太天真了,我开始也是这样想的,后面输出之后发现结果不对,输出的还是undefined。为什么呢??
因为我把方法写在了对象里,而对象的括号是不能封闭作用域的。所以此时的this还是指向全局对象。
所以,通过以上的错误可以提醒我们,最好不要用箭头函数作为对象的方法。
我们需要重新举一个例子,如下
function Person () {
this.name = 'little bear',
this.age = 18
let self = this
setInterval(function sayHello () {
console.log('我叫' + self.name + '我今年' + self.age + '岁!')
}, 1000)
}
let p = new Person()
缓存this,然后输出,能达到我们想要的结果。
把上述例子改为箭头函数的形式如下
function Person () {
this.name = 'little bear',
this.age = 18
setInterval(() => {
console.log('我叫' + this.name + '我今年' + this.age + '岁')
},1000)
}
let p = new Person()
我们可以看到,箭头函数使用了定义时上下文的this,且与在哪里调用没有关系。
3.2 不绑定arguments
箭头函数还有一个比较有特点的地方就是其不绑定arguments,即如果你在箭头函数中使用arguments参数不能得到想要的内容。
let arrowfunc = () => console.log(arguments.length)
arrowfunc()
//output
arguments is not defined
所以在箭头函数中我们是不能直接使用arguments对象的,但是如果我们又想获得函数的参数怎么办呢?
我们可以使用剩余参数来取代arguments剩余参数详情
let arrowfunc = (...theArgs) => console.log(theArgs.length)
arrowfunc(1,2)
//output
2
四 什么时候不能用箭头函数
前面我们已经看到了很多关于es6箭头函数的好处,也看到了箭头函数的一些不足。那么我们应该在什么时候使用箭头函数,而什么时候最好不要使用呢?
1.作为对象的方法
在写这篇博客的例子时,由于本人的水平确实有限,导致了篇头出现的错误。不过我也想由此告诉大家,最好不要在对象的方法中使用箭头函数,这样可能会导致一些问题的产生。除非你很熟悉箭头函数。
2.不能作为构造函数
由于箭头函数的this不绑定的特点,所以不能使用箭头函数作为构造函数,实际上如果这样做了,也会报错。
3.定义原型方法
function Person (name){
this.name = name
}
Person.prototype.sayHello = () => {
console.log(this)
}
var p1 = new Person()
p1.sayHello()
//output
window对象
这里的this指向的是window对象,这点和在对象方法中定义有点像
五 总结
箭头函数由于其代码的简洁性和不绑定调用者this的特点,在非方法函数中使用是最合适的,而在方法函数中使用,需要特别注意它的this绑定问题,如果需要动态的修改this,最好还是不要使用箭头函数了。所以永远没有一个解决方案能解决所有事情,只有合适的应用场景。
ES6 — 箭头函数的更多相关文章
- es6箭头函数讲解
es6箭头函数的用法 箭头函数是es6的一种函数的简写方法. 如下: var f = v = > v; //等同于 var f = function(v){ return v; } var su ...
- es6箭头函数 this 指向问题
es5中 this 的指向 var factory = function(){ this.a = 'a'; this.b = 'b'; this.c = { a:'a+', b:function(){ ...
- 前端分享----JS异步编程+ES6箭头函数
前端分享----JS异步编程+ES6箭头函数 ##概述Javascript语言的执行环境是"单线程"(single thread).所谓"单线程",就是指一次只 ...
- ES6 箭头函数 this 指向
ES6 箭头函数 this 指向 箭头函数有几个使用注意点: 函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象. 不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个 ...
- ES6 箭头函数(Arrow Functions)
ES6 箭头函数(Arrow Functions) ES6 可以使用 "箭头"(=>)定义函数,注意是函数,不要使用这种方式定义类(构造器). 一.语法 具有一个参数的简单函 ...
- ES6箭头函数基本用法
ES6箭头函数基本用法 ``` window.onload = function(){ alert(abc); } //箭头函数 window.onload = ()=>{ alert(&quo ...
- ES6 箭头函数this指向问题
var name = "window"; var person1 = { name: "person1", show1: function() { consol ...
- Vue ES6箭头函数使用总结
Vue ES6箭头函数使用总结 by:授客 QQ:1033553122 箭头函数 ES6允许使用“箭头”(=>)定义函数: 函数不带参数 定义方法:函数名称 = () => 函数体 ...
- ES6 -箭头函数 ,对象的函数解构
ES6 -箭头函数: //es6 中的箭头函数和扩展 //es5的写法 // function add(a,b){ // return a + b; // } // add(1,2); //3 fun ...
随机推荐
- 合并两个dt
C#代码中实现两个表(DataTable)的关联查询(JOIN) 之前通常都是使用SQL直接从数据库中取出表1和表2关联查询后的数据,只需要用一个JOIN就可以了,非常方便.近日遇到一种情况,两个 ...
- WPF中的动画
动画无疑是WPF中最吸引人的特色之一,其可以像Flash一样平滑地播放并与程序逻辑进行很好的交互.这里我们讨论一下故事板. 在WPF中我们采用Storyboard(故事板)的方式来编写动画,为了对St ...
- JS-Object (3) JSON; Event Object相关知识(事件冒泡,事件监听, stopPropagation()
通常用于在网站上表示和传输数据 使用JavaScript处理JSON的所有工作,包括访问JSON对象中的数据项并编写自己的JSON. JSON text基本上就像是一个JavaScript对象,这句话 ...
- ShardedJedis的使用
假定有2个 redis 服务实例(A和B)在运行,在客户端进行 set 操作: set a0 xxx set a1 xxx set a2 xxx set a3 xxx 我们希望a0, a1, a2, ...
- zk键值数据结构
首先看一张zk官网上的图: zk为我们提供了一种类似于文件存储的树形数据结构,那么它是如何实现的呢? 先假定我们有一个map,以路径名作为键,以节点作为值,如下: “/” -> 节点1,“/ap ...
- 使用GAN 进行异常检测——anoGAN,TODO,待用于安全分析实验
先说实验成功的代码: git clone https://github.com/tkwoo/anogan-keras.git mkdir weights python main.py --mode t ...
- 深入理解MyBatis中的一级缓存与二级缓存
http://blog.csdn.net/weixin_36380516/article/details/73194758 先说缓存,合理使用缓存是优化中最常见的,将从数据库中查询出来的数据放入缓 ...
- [需要补充]javaEE中servlet方法service与doXXX的关系
刚开始很模糊他们的关系,不清楚 service protected void service(HttpServletRequest req, HttpServletResponse resp) thr ...
- dnspod 动态域名的使用。openwrt使用dnspod动态域名解析。
这里主要说的是linux shell下的使用. 先看接口说明: 接口地址: https://dnsapi.cn/Record.Ddns HTTP请求方式: POST 请求参数: 公共参数 domain ...
- (转载)Hibernate的事务管理
Hibernate的事务管理 事务(Transaction)是工作中的基本逻辑单位,可以用于确保数据库能够被正确修改,避免数据只修改了一部分而导致数据不完整,或者在修改时受到用户干扰.作为一名软件设计 ...