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 ...
随机推荐
- mycat分布式mysql中间件(自增主键)
一.全局序列号 全局序列号是MyCAT提供的一个新功能,为了实现分库分表情况下,表的主键是全局唯一,而默认的MySQL的自增长主键无法满足这个要求.全局序列号的语法符合标准SQL规范,其格式为:nex ...
- golang martini 源码阅读笔记之martini核心
继上一篇关于inject注入的笔记,理解了martini的关键核心之一:依赖注入.注入回调函数,由运行时进行主动调用执行.这一篇主要是注解martini的骨架martini.go的实现,下面先从一个简 ...
- AI学习路径
- thinkphp条件查询
1.这是我在做项目的时候编写的: $profit = M('shipping_types',' ','DB_PROFIT');//没有表前缀,在M函数的第二个参数就为空. //条件$field = a ...
- 双十一用python秒杀京东好货!
好久没用python了,都写不来了. 需要用到selenium 和 Chromedriver: 我只是记录一下几个坑: 第一个坑:自己电脑里安装了两个版本的python ,3.5和3.6 结果我在pi ...
- James Whittaker:经营成功的测试职业生涯
转注:这篇文章出自 James A. Whittaker,Google的工程总监,负责Google部分产品的测试,包括Chrome.地图.GoogleWebApp.在加盟Google之前,James在 ...
- 配置pycharm 一键安装 requirements.txt,一键生成requirements.txt
如上配置 打开项目,在requirements.txt上点右键,就可以安装了. 安装效果如下: 可以看出运行的命令是 C:\Python\Python36/scripts/pip install ...
- Pycharm(四)常用快捷键
Ctrl + Alt +S 进入设置Ctrl + Alt + L 代码格式化Ctrl + Alt + I 自动缩进Ctrl + D 复制当前行 Ctrl + / 注释(取消注释)当前行 再有什么用的多 ...
- 1.学习dubbo
1.安装虚拟机 http://www.cnblogs.com/yun965861480/p/6246396.html 2.配置网络 http://www.cnblogs.com/yun96586148 ...
- 电脑同时安装python2和python3, 如何实现切换使用
由于历史原因,Python有两个大的版本分支,Python2和Python3,又由于一些库只支持某个版本分支,所以需要在电脑上同时安装Python2和Python3,因此如何让两个版本的Python兼 ...