JavaScript基础之this和箭头函数详析


Posted in Javascript onSeptember 05, 2019

箭头函数不会创建自己的this,它只会从自己的作用域链的上一层继承this。

由于箭头函数没有自己的this指针,通过 call() 或 apply() 方法调用一个函数时,只能传递参数(不能绑定this),他们的第一个参数会被忽略。

前言

阅读下面的内容要先看下《你不知道的javascript(上)》中的第二部分:this和对象原型(里面对于this指向的理论部分主要来源于该书)。

问题

这周在写代码的时候,听同事在说箭头函数无法更改this的指向,并且使用下面代码进行验证:

// (1) 使用箭头函数,this一直指向window
var a = 0
var obj1 = {
  a: 1,
  fn: () => { console.log(this.a) }
}
obj1.fn() // 结果:0

var obj2 = {
  a: 2
}
obj2.fn = obj1.fn
obj2.fn() // 结果:0
// (2)不使用箭头函数,this的指向会更改
var obj3 = {
  a: 3,
  fn: function() { console.log(this.a) }
}
obj3.fn() // 结果:3

第一段代码,无论fn绑定在哪个对象上,this.a始终指向全局的a(在非严格模式下的浏览器中我们可认为是window)

然而,这种说法是有问题(我认为)。

先理解this

this代表什么取决于:

  1. 调用位置
  2. 四种绑定规则
var a = 0
test() // 调用位置在此,通过【默认绑定规则】,可知test的this绑定到了window上
function test() {
  console.log(this) // this是window
  var obj1 = {
    a: 1,
    fn: function() {
      console.log(this) // this是obj1
      console.log(this.a) 
    }
  }
  obj1.fn() // 调用位置在此,通过【隐式绑定规则】,可知fn中的this绑定到了obj1上
  var obj2 = {
    a: 2
  }
  obj2.fn = obj1.fn
  obj2.fn() // 调用位置在此,【隐式绑定规则】,可知fn内的this绑定到了obj2
}

箭头函数中的this

其实这么起标题不太准确(然而想不出好的名字),因为箭头函数是不会创建自己的this的(MDN),那么下面代码的this是来源于哪里的呢?

var obj3 = {
  a: 3,
  fn: () => {
    console.log(this.a)
  }
}
obj3.fn() // 调用位置在此,this指向window
arrowFoo1() // (1)此处是调用位置,使用【默认的绑定规则】,this = window
function arrowFoo1() {
  var obj1 = {
    vv: 'svv1',
    fn: () => {
      console.log(this.vv, 'vv的值是')
    }
  }
  // (2)调用位置是此处,若fn不是箭头函数,那么这里也会有自己的this(即【隐式调用规则】,this绑定为obj1),而fn是箭头函数,则它没有this,那么fn内部调用的this是谁?
  // 这时候需要根据作用域的规则,往外层查找,找到哪里?找到调用obj1.fn的调用栈,即arrowFoo1函数的this,那么从(1)中可知,那个this指向的是window
  obj1.fn()
  var obj2 = {
    vv: 'svv2',
  }
  obj2.fn = obj1.fn
  obj2.fn()
}
function arrowFoo2() {
  var vv = '哦哦哦哦哦'
  console.log(this.vv, 'vv的值是')
}

因此,箭头函数里面要是用到了this,那么其实它是通过作用域链,往外进行查找的,找到了就直接返回咯。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
js判断变量是否空值的代码
Oct 26 Javascript
JQuery从头学起第三讲
Jul 06 Javascript
jquery下为Event handler传递动态参数的代码
Jan 06 Javascript
js简单实现交换Li的值
May 22 Javascript
Ext GridPanel加载完数据后进行操作示例代码
Jun 17 Javascript
JavaScript中的console.trace()函数介绍
Dec 29 Javascript
使用vue.js开发时一些注意事项
Apr 27 Javascript
AngularJS 视图详解及示例代码
Aug 17 Javascript
Node.js开启Https的实践详解
Oct 25 Javascript
详解使用Typescript开发node.js项目(简单的环境配置)
Oct 09 Javascript
微信小程序页面间传递数组对象方法解析
Nov 06 Javascript
深入分析jQuery.one() 函数
Jun 03 jQuery
layer.js open 隐藏滚动条的例子
Sep 05 #Javascript
Layui数据表格跳转到指定页的实现方法
Sep 05 #Javascript
使用easyui从servlet传递json数据到前端页面的两种方法
Sep 05 #Javascript
BootStrap表单验证中的非Submit类型按钮点击时触发验证的坑
Sep 05 #Javascript
利用d3.js制作连线动画图与编辑器的方法实例
Sep 05 #Javascript
javascript之分片上传,断点续传的实际项目实现详解
Sep 05 #Javascript
layui 实现table翻页滚动条位置保持不变的例子
Sep 05 #Javascript
You might like
smtp邮件发送一例
2006/10/09 PHP
PHP中基于ts与nts版本- vc6和vc9编译版本的区别详解
2013/04/26 PHP
php页面防重复提交方法总结
2013/11/25 PHP
ThinkPHP的cookie和session冲突造成Cookie不能使用的解决方法
2014/07/01 PHP
php操作(删除,提取,增加)zip文件方法详解
2015/03/12 PHP
学习php设计模式 php实现建造者模式
2015/12/07 PHP
PHP购物车类Cart.class.php定义与用法示例
2016/07/20 PHP
PHP通过get方法获得form表单数据方法总结
2018/09/12 PHP
jquery 插件学习(四)
2012/08/06 Javascript
JavaScript子类用Object.getPrototypeOf去调用父类方法解析
2013/12/05 Javascript
javascript获取和判断浏览器窗口、屏幕、网页的高度、宽度等
2014/05/08 Javascript
jQuery实现自定义下拉列表
2015/01/05 Javascript
JavaScript中用于四舍五入的Math.round()方法讲解
2015/06/15 Javascript
Jquery揭秘系列:ajax原生js实现详解(推荐)
2016/06/08 Javascript
基于CSS3和jQuery实现跟随鼠标方位的Hover特效
2016/07/25 Javascript
JAVA Web实时消息后台服务器推送技术---GoEasy
2016/11/04 Javascript
vue 的keep-alive缓存功能的实现
2018/03/22 Javascript
vue实现城市列表选择功能
2018/07/16 Javascript
Vue2.0点击切换类名改变样式的方法
2018/08/22 Javascript
[01:27]2014DOTA2展望TI 剑指西雅图IG战队专访
2014/06/30 DOTA
[02:08]2014DOTA2国际邀请赛 430专访:力争取得小组前二
2014/07/11 DOTA
python实现给字典添加条目的方法
2014/09/25 Python
python中实现定制类的特殊方法总结
2014/09/28 Python
python执行shell获取硬件参数写入mysql的方法
2014/12/29 Python
Python使用Tkinter实现机器人走迷宫
2018/01/22 Python
Python简单获取二维数组行列数的方法示例
2018/12/21 Python
使用Python Pandas处理亿级数据的方法
2019/06/24 Python
Python使用pymysql模块操作mysql增删改查实例分析
2019/12/19 Python
Python批量将图片灰度化的实现代码
2020/04/11 Python
Python实现查找数据库最接近的数据
2020/06/08 Python
Django自定义YamlField实现过程解析
2020/11/11 Python
韩国家庭购物网上商店:Nsmall
2017/05/07 全球购物
2014小学教师年度考核工作总结
2014/12/03 职场文书
公司保洁员岗位职责
2015/02/13 职场文书
python绘图subplots函数使用模板的示例代码
2021/04/30 Python
Spring boot应用启动后首次访问很慢的解决方案
2021/06/23 Java/Android