箭头函数(Arrow functions),是ECMAScript2015中新加的特性,它的产生,主要有以下两个原因:一是使得函数表达式(匿名函数)有更简洁的语法,二是它拥有词法作用域的this值,也就是说它跟父作用域共享this,不会新产生自己作用域下的this, arguments, super 和 new.target 等对象。

使用箭头函数特性

在JavaScript代码中,函数无处不在。假设页面上有一个特定的按钮,它的id是‘clickMe’,点击它后,页面弹出“Hello,Arrow functions!”,为实现这个效果,我们会像下面这样编写JavaScript代码:

    $(function(){
$('#clickMe').click(function(){
alert('Hello,Arrow functions!');
})
})

以上是传统的JavaScript写法,给click方法传入一个函数作为参数,这个函数通常都需要按照以下格式输入:function(){}。使用箭头函数后,代码如下:

    $(function(){
$('#clickMe').click(()=>{alert('Hello,Arrow functions!')});
})

上面的例子比较简单,再来看一个Promise链的例子:

    function getUserInfo(id){
return getUsers(id).
then(function(users){return users[0]}).
then(checkUser).
then(function(user,userInfo){return userInfo }).
catch(function(error){console.log(error.message)})
}

使用箭头函数简化上面的例子,代码如下:

    function getUserInfo(id){
return getUsers(id).
then(users => users[0]).
then(checkUser).
then((user,userInfo)=>userInfo).
catch(error=>console.log(error.message))
}

从简化后的代码来看,不难发现,所有回调函数中的function 和 {}不见了,而且回调函数都在一行表示,当只有一个参数时,()也消失了;由于{}消失了,里面的return也消失了,代码看起来更加清晰、简洁了。前面提到单行表示回调函数的时候,{}被省略了,假如这时候我们要返回一个对象(包括空对象)的话,该怎么处理呢?这是个坑,一般按如下方式书写代码:

    const emptyObject = ()=>({})

箭头函数里面的this

开头那里已经提到了,箭头函数没有自己的this值,它跟父作用域共享this,箭头函数内部也没有constructor方法,也没有prototype,所以箭头函数不支持new操作。

在箭头函数之前,每个新定义的函数都有自己的this值,例如,构造函数的this指向一个新的对象,如果是‘严格模式’,则this值为undefined,如果函数作为对象的方法被调用,则该函数的this指向了那个调用它的对象。在JavaScript面向对象编程中,this的指向是让新手很头疼的问题。

function Person(){
//构造函数的this指向实例对象自己
this.age = 25;
setInterval(function growUp(){
//在非严格模式下,growUp函数定义了其内部的this,其指向window对象,不同于构造函数Person()定义的this
this.age++;
},1000);
}
var p = new Person();

在箭头函数之前,我们是如何使growUp函数内部的this也指向构造函数Person()的实例对象的呢?如下:

function Person() {
var self = this;
self.age = 25;
setInterval(function growUp(){
self.age++;
});
}
var p = new Person();

也就是通过新增一个变量来指向期望的this对象,除此之外,还可以使用 bind 函数,把期望的 this 值传递给 growUp() 函数。

function Person() {
this.age = 25;
setInterval(function growUp(){
this.age++;
console.log(this.age);
}.bind(this),1000);
}
var p = new Person();

由于箭头函数会捕获其所在上下文的this值,来作为自己的this值,所以我们可以这样修改上述例子的代码:

function Person() {
this.age = 25;
setInterval(()=>{
this.age++;//这里的this也指向Person对象
},1000);
}

使用 call 或 apply 调用

箭头函数的 this 始终指向函数定义时的 this,而非执行时。下面看一个试图改变箭头函数 this 指针的例子:

var x = 1,
o = {
x : 10,
test : () => this.x
}; o.test(); // 1
o.test.call(o); // 仍旧是1

由于 this 已经在词法层面完成了绑定,通过 call() 或 apply() 方法调用一个函数时,只是传入了参数而已,对 this 并没有什么影响:

var adder = {
base : 1, add : function(a) {
var f = v => v + this.base;
return f(a);
}, addThruCall: function(a) {
var f = v => v + this.base;
var b = {
base : 2
}; return f.call(b, a);
}
}; console.log(adder.add(1)); // 输出 2
console.log(adder.addThruCall(1)); // 仍然输出 2,而不是3
 
 
 
 
 
 
 

简单理解ECMAScript2015中的箭头函数新特性的更多相关文章

  1. 简单理解ECMAScript2015中的Promise

    ECMAScript6中新增了Promise对象, 所谓Promise对象,即代表着一个还未完成,但将来某时会完成的操作(通常是异步操作).使用Promise对象,我们就可以避免陷入函数层层嵌套的‘回 ...

  2. 前端笔记之ES678&Webpack&Babel(中)对象|字符串|数组的扩展&函数新特性&类

    一.对象的扩展 1.1对象属性名表达式 ES6可以在JSON中使用[]包裹一个key的名字.此时这个key将用表达式作为属性名(被当做变量求值),这个key值必须是字符串. var a = 'name ...

  3. JS中的箭头函数与this

    转载自:https://juejin.im/post/5aa1eb056fb9a028b77a66fd#heading-1 JavaScript在ES6语法中新增了箭头函数,相较于传统函数,箭头函数不 ...

  4. ES6中的箭头函数与普通函数的区别

    箭头函数与普通函数的区别 1.语法上更加简洁.清晰 基本语法: // 关于箭头函数的参数 // 如果箭头函数没有参数,直接写一个括号即可 let fun1 = () => { console.l ...

  5. 简单理解Struts2中拦截器与过滤器的区别及执行顺序

    简单理解Struts2中拦截器与过滤器的区别及执行顺序 当接收到一个httprequest , a) 当外部的httpservletrequest到来时 b) 初始到了servlet容器 传递给一个标 ...

  6. ES6中的箭头函数

    关于函数表达式中的this:自动引用正在调用当前方法的.前的对象1.obj.fun()中的this fun中的this -> obj2.new Fun() Fun中的this -> 正在创 ...

  7. 理解javascript中的回调函数(callback)【转】

    在JavaScrip中,function是内置的类对象,也就是说它是一种类型的对象,可以和其它String.Array.Number.Object类的对象一样用于内置对象的管理.因为function实 ...

  8. C++ 11学习和掌握 ——《深入理解C++ 11:C++11新特性解析和应用》读书笔记(一)

    因为偶然的机会,在图书馆看到<深入理解C++ 11:C++11新特性解析和应用>这本书,大致扫下,受益匪浅,就果断借出来,对于其中的部分内容进行详读并亲自编程测试相关代码,也就有了整理写出 ...

  9. ABAP 7.40, SP08 中的 Open SQL 新特性

    1,使用 data_source~*指定列 在7.40, SP08中,可以在SELECT语句中使用data_source~*来指定选取不同的数据库表.视图的全部列来作为结果集.它也可以和单独指定的列c ...

随机推荐

  1. 在Hadoop-2.2.0集群上安装 Hive-0.13.1 with MySQL

    fesh个人实践,欢迎经验交流!本文Blog地址:http://www.cnblogs.com/fesh/p/3872872.html 软件环境 操作系统:Ubuntu14.04 JDK版本:jdk1 ...

  2. DataTable 怎样设置列宽? DataTable中已经有数据了怎样在现实的时候设置它的列宽?

    首先要理解 DataTable是一个虚拟表,里面存有数据列,既然是虚拟的就不能够为它去设置宽度,如果设置的话可以对其绑定的控件进行设置.例如:绑定的控件对象为DataGridView那么可以这样 da ...

  3. ArcEngine10.1二次开发错误: 无法嵌入互操作类型,请改用适用的接口

    在之前配置ArcEngine.VS2010二次开发程序的时候,遇见"无法嵌入互操作类型,请改用适用的接口"的错误,在网上查了下,下面引用解决方法. 解决方式为在提示错误的引用上面右 ...

  4. jqyery dataTable 基本用法

    一:官方网站:[http://www.datatables.net/] 二:基本使用:[http://www.guoxk.com/node/jquery-datatables] 1.DataTable ...

  5. Contacts群组添加成员,多选列表过滤已添加数据

    Group添加联系人时,Contacts默认设计不会过滤已分组的联系人.之前看到小米,oppo都做过过滤,一直懒得改. 最近客户要求group添加成员时,不显示已分组的联系人,故记录一下实现过程. p ...

  6. linux(ubuntu)安装时遇到的问题

    window环境下安装linux虚拟机=时,由于在初始系统语言选择了中文,当linux虚拟机安装成功后, 按[Ctrl + alt +f1~f6]任一一键都行,进入到命令行模式,这时你会发现,哎,我的 ...

  7. 【动态规划】bzoj1664 [Usaco2006 Open]County Fair Events 参加节日庆祝

    将区间按左端点排序. f(i)=max{f(j)+1}(p[j].x+p[j].y<=p[i].x && j<i) #include<cstdio> #incl ...

  8. Log4net日志GUI配置工具

    关于log4net的配置文章在园子里真的很多,但是有关GUI界面配置的文章确定太少,改写了一个以前很早的工具 以前的那个有很多的问题,这个基本的大的问题没有,可能一个小问题还是需要修改下,基本功能肯定 ...

  9. [SmartFoxServer概述]Zones和Rooms结构

    Zones和Rooms结构: 相对于SFS 1.X而言,在Zones和Rooms的配置上,SFS2X有了显著的改善.尤其是我们建立了房组这样一个简单的概念,它允许在一个逻辑组中管理Rooms,从而独立 ...

  10. #笔记#JavaScript进阶篇一

    #JavaScript进阶篇 http://www.imooc.com/learn/10 #认识DOM #window对象 浏览器窗口可视区域监测—— 在不同浏览器(PC)都实用的 JavaScrip ...