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 相关文章推荐
仅img元素创建后不添加到文档中会执行onload事件的解决方法
Jul 31 Javascript
面向对象继承实例(a如何继承b问题)(自写)
Jul 01 Javascript
JS生成不重复随机数组的函数代码
Jun 10 Javascript
老生常谈JavaScript 正则表达式语法
Aug 20 Javascript
jQuery事件用法详解
Oct 06 Javascript
基于JavaScript实现数码时钟效果
Mar 30 Javascript
在Vue中使用Compass的方法
Mar 02 Javascript
Vue CLI3 开启gzip压缩文件的方式
Sep 30 Javascript
详解js动态获取浏览器或页面等容器的宽高
Mar 13 Javascript
vue实现微信分享链接添加动态参数的方法
Apr 29 Javascript
Vue实现push数组并删除的例子
Nov 01 Javascript
解决Echarts 显示隐藏后宽度高度变小的问题
Jul 19 Javascript
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
PHP 抓取新浪读书频道的小说并生成txt电子书的代码
2009/12/18 PHP
PDO版本问题 Invalid parameter number: no parameters were bound
2013/01/06 PHP
destoon切换城市后实现logo旁边显示地区名称的方法
2014/08/21 PHP
PHP7.0版本备注
2015/07/23 PHP
利用PHP自动生成印有用户信息的名片
2016/08/01 PHP
php简单截取字符串代码示例
2016/10/19 PHP
微信公众号实现会员卡领取功能
2017/06/08 PHP
做网页的一些技巧
2007/02/01 Javascript
网页中实现浏览器的最大,最小化和关闭按钮
2007/03/12 Javascript
javascript 框架小结 个人工作经验
2009/06/13 Javascript
Jquery ui css framework
2010/06/28 Javascript
经过绑定元素时会多次触发mouseover和mouseout事件
2014/02/28 Javascript
采用call方式实现js继承
2014/05/20 Javascript
JavaScript获取按钮所在form表单id的方法
2015/04/02 Javascript
Jquery实时监听input value的实例
2017/01/26 Javascript
JavaScript实现左右下拉框动态增删示例
2017/03/09 Javascript
node.js学习之断言assert的使用示例
2017/09/28 Javascript
详解mpvue开发小程序小总结
2018/07/25 Javascript
js 计算图片内点个数的示例代码
2019/04/04 Javascript
JavaScript中继承原理与用法实例入门
2020/05/09 Javascript
[59:15]完美世界DOTA2联赛PWL S2 LBZS vs FTD.C 第一场 11.20
2020/11/20 DOTA
Python实现的Google IP 可用性检测脚本
2015/04/23 Python
python3+PyQt5 创建多线程网络应用-TCP客户端和TCP服务器实例
2019/06/17 Python
Pytest参数化parametrize使用代码实例
2020/02/22 Python
基于python模拟bfs和dfs代码实例
2020/11/19 Python
Python 无限级分类树状结构生成算法的实现
2021/01/21 Python
pytorch 把图片数据转化成tensor的操作
2021/03/04 Python
6种非常炫酷的CSS3按钮边框动画特效
2016/03/16 HTML / CSS
AmazeUI 手机版页面的顶部导航条Header与侧边导航栏offCanvas的示例代码
2020/08/19 HTML / CSS
阿迪达斯加拿大官网:Adidas加拿大
2016/08/25 全球购物
Footshop罗马尼亚:最好的运动鞋选择
2019/09/10 全球购物
美国名表在线商城:Ashford(支持中文)
2019/09/24 全球购物
大学生简单自荐信
2013/11/10 职场文书
工作检讨书大全
2015/01/26 职场文书
酒店保洁员岗位职责
2015/02/26 职场文书
解决Jupyter-notebook不弹出默认浏览器的问题
2021/03/30 Python