相对于普通函数的区别

新的书写方式

this 的改变

不能当构造函数

没有 prototype 属性

没有 arguments 对象

新的书写方式

书写方式很简单!直接看下图,

常规方式写一个函数
const fun = function(number){
return number * 2
}
 
使用箭头函数

const fun = (number) => {
return number * 2
}
 
如果只有一个参数,还可以省略前面的小括号
const fun = number => {
return number * 2
}
 
如果只有一条执行语句,甚至可以省略后面的大括号,而且可以也不能写 return

const fun = number => number * 2 
 
也可以写成立即执行函数

const fun = (() => 3 * 2)()  //

this的改变

执行上下文

讨论箭头函数的 this 之前,不得不再熟悉一下 执行上下文(Execution Context),因为 this 指针(this value) 就存储在执行上下文中。

执行上下文保存着函数执行所需的重要信息,其中有三个属性:变量对象(variable object),作用域链(scope chain),this指针(this value),它们影响着变量的解析、变量作用域、函数 this 的指向。执行上下文分为 全局执行上下文 和 函数执行上下文。

全局代码开始执行前,会以 window 为目标产生一个全局执行上下文, 开始对代码预编译,这时候 this 指向的就是 window,接着开始执行全局代码。

当函数代码开始执行前,会以函数为目标产生一个函数执行上下文,开始对该函数预编译,这时候 this 的指向要分几种情况(下面讨论),接着开始执行函数代码,函数代码执行完后函数执行上下文就被会删除。多个函数会产生多个执行上下文。

上面说到函数预编译的 this 分下面四种情况:

第一种: 函数自主调用 如 fun() 或者是 普通的立即执行函数(区别于箭头函数方式的立即执行函数), this 指向 window;

第二种: 函数被调用,当函数被某个对象调用时,函数产生的执行上下文中的 this 指向 该对象;

第三种: 通过 call() apply() bind() 方法改变 this,this 指向被传入的 第一个参数;

第四种: 在构造函数中,this 指向被创建的 实例

由于箭头函数是不能通过 call() apply() bind() 方法改变 this,也不能当做构造函数,所以接下来只演示第一和第二种情况的代码

var a = {
origin: 'a',
b: {
origin: 'b',
show: function(){
    var origin = 'show';
console.log(this.origin);
  }
}
}
var origin = 'window'
a.b.show(); // 因为 b 对象调用了 show 函数,所以 show 函数的执行上下文中的 this 指针指向 b 对象
var fun = a.b.show; // 注意这里是将 show 函数赋值给fun,相当于 var fun = function(){console.log(this)}
fun(); // 因为 fun 是自主调用,所以 this 指针指向 window,自然就打印 window 对象了

可能有人会有这个疑惑:a.b.show() 中,a 调用了 b,是不是 b 的 this 指向 a 了?

前面也说到了,this 储存在执行上下文中,而只有 全局 和 函数 才会产生执行上下文,在执行上下文里记录着 this,而 b 是全局中 a 对象里面的一个对象,不存在谁调用它,它的 this 就是谁的说法。

接下来理解箭头函数中的 this 就非常容易了。

箭头函数中的 this

首先,箭头函数不会创建自己的 this,它只会从自己的作用域链上找父级执行上下文的 this,而不是谁调用它,它的 this 就是谁。所以箭头函数中的 this,取决于你上层执行上下文的 this 。

下例中,

obj 分别调用了 show1 和 show2 两个方法,所以show1 和 show2 中的 this 都是指向 obj,

show1 中, setTimeout 里面是箭头函数,从作用域链中找到 show1 中的 this,所以它的 this 就是 obj 对象;

show2 中,setTimeout 里面的函数换成普通函数,函数自主调用,所以他的 this 就是 window 对象

var id = 0;
var obj = {
id: 1,
show1: function(){
setTimeout(() => {
console.log(this.id)
}, 1000)
},   show2: function(){
    setTimeout(function(){
      console.log(this.id)
    }, 2000)
  }
} obj.show1(); // 打印 1
obj.show2(); // 打印 0

不能当成构造函数

var Foo = () => {};
var foo = new Foo(); // TypeError: Foo is not a constructor

没有 prototype 属性

var Foo = () => {};
console.log(Foo.prototype); // undefined

没有 arguments 对象

在大多数情况下,使用' ... ' 运算符是比使用 arguments 对象的更好选择。

function foo(...arg) {
return arg;
}
foo(1, 2, 3, 4); //
function foo(...numbers) {
numbers.forEach((number)=>{
console.log(number);
})
}
foo(1, 2, 3, 4); // 1 2 3 4

ES6之箭头函数深入理解的更多相关文章

  1. ES6中箭头函数的作用

    我们知道在ES6中,引入了箭头函数,其本质就是等同有ES5中的函数.类似于下面的写法: let test1=() => “abc”; let test2=() => { return “a ...

  2. Es6中箭头函数与普通函数的区别

    Es6中箭头函数与普通函数的区别? 普通function的声明在变量提升中是最高的,箭头函数没有函数提升 箭头函数没有属于自己的this,arguments 箭头函数不能作为构造函数,不能被new,没 ...

  3. es6的箭头函数和es5的function函数区别

    一.es6的箭头函数es6箭头函数内部没有this,使用时会上朔寻找最近的this不可以做构造函数,不能使用new命令,因为没有this函数体内没有arguments,可以使用rest参数代替不能用y ...

  4. 初步探究ES6之箭头函数

    今天要介绍的是ES6中的箭头函数. 语法 我们先来看看箭头函数的语法: ([param] [, param]) => { statements } param => expression ...

  5. ES6使用箭头函数注意点

    新事物也是有两面性的,箭头函数有他的便捷有他的优点,但是他也有缺点,他的优点是代码简洁,this提前定义,但他的缺点也是这些,比如代码太过简洁,导致不好阅读,this提前定义,导致无法使用JS进行一些 ...

  6. Es6 之箭头函数 初学

    不积跬步,无以至千里;不积小流,无以成江海! // ES5 var selected = allJobs.filter(function (job) { return job.isSelected() ...

  7. 关于es6的箭头函数使用与内部this指向

    特型介绍:箭头函数是ES6新增的特性之一,它为JS这门语言提供了一种全新的书写函数的语法. 'use strcit'; let arr = [1,2,3]; //ES5 let es5 = arr.m ...

  8. ES6笔记② 箭头函数

    特性介绍 箭头函数是ES6新增的特性之一,它为JS这门语言提供了一种全新的书写函数的语法. //ES5 function fun(x,y){ return x+y; } console.log(fun ...

  9. 关于ES6 用箭头函数后的 this 指向问题

    最近写完小程序后, 开始学习React, 因为有编译器, 就直接用ES6 新语法了, 中间自然离不开  () => { console.log('箭头函数的this是指向哪的问题')}; var ...

随机推荐

  1. Codeforces Round #148 (Div. 1)

    A wool sequence 表示一个序列中能够找到一个连续的子区间使得区间异或值为0 那么求的是不含这样的情况的序列个数 题目中数据范围是.在0~2^m - 1中选n个数作为一个序列 n和m都是1 ...

  2. Objective-C之成魔之路【10-继承性】

    郝萌主倾心贡献.尊重作者的劳动成果.请勿转载. 假设文章对您有所帮助,欢迎给作者捐赠,支持郝萌主.捐赠数额任意.重在心意^_^ 我要捐赠: 点击捐赠 Cocos2d-X源代码下载:点我传送 继承性是面 ...

  3. C#WinForm窗体监听/拦截操作动作

    C#中的事件也是通过封装系统消息来实现的,如果你在WndProc函数中不处理该消息 那么,它会被交给系统来处理该消息,系统便会通过代理来实现鼠标单击的处理函数,因此你可以通过 WndProc函数来拦截 ...

  4. Python调用C/Fortran混合的动态链接库--上篇

    内容描述: 在32位或64位的windows或GNU/Linux系统下利用Python的ctypes和numpy模块调用C/Fortran混合编程的有限元数值计算程序 操作系统及编译环境: 32bit ...

  5. (转载)解决MySql 数据库 提示:1045 access denied for user 'root'@'localhost' using password yes

    今天想用用MySQL 数据库  谁知道老提示 1045 access denied for user 'root'@'localhost' using password yes 最后在csdn 上找到 ...

  6. 在VC中动态加载ODBC的方法

    在使用VC.VB.Delphi等高级语言编写数据库应用程序时,往往需要用户自己在控制面板中配置ODBC数据源.对于一般用户而言,配置ODBC数据源可能是一件比较困难的工作.而且,在实际应用中,用户往往 ...

  7. 检測磁盘驱动的健康程度SMART

    在server中,全部组件中一般最easy坏掉的就是磁盘.所以一般採取RAID来保证系统的稳定性,通过冗余磁盘的方式防止磁盘故障. 现代硬件驱动器一般支持SMART(自我监測分析和报告技术),它可以监 ...

  8. 防sql注入 盲注等措施 ESAPI的使用

    SQL注入往往是在程序员编写包含用户输入的动态数据库查询时产生的,但其实防范SQL注入的方法非常简单.程序员只要a)不再写动态查询,或b)防止用户输入包含能够破坏查询逻辑的恶意SQL语句,就能够防范S ...

  9. List 调用 remove 方法时抛出 java.lang.UnsupportedOperationException 异常原因

    原因 使用 Arrays.asList(arr) 转换的 List 并不能进行 add 和 remove 操作.       Arrays.asList(arr) 返回的类型是 Aarrays$Arr ...

  10. JAVA中Stack和Heap的区别

    http://m.blog.csdn.net/wl_ldy/article/details/5935528