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 相关文章推荐
json的定义、标准格式及json字符串检验
May 11 Javascript
jquery列表拖动排列(由项目提取相当好用)
Jun 17 Javascript
JavaScript检查某个function是否是原生代码的方法
Aug 20 Javascript
javascript中parseInt()函数的定义和用法分析
Dec 20 Javascript
纯HTML5制作围住神经猫游戏-附源码下载
Aug 23 Javascript
vue.js将unix时间戳转换为自定义时间格式
Jan 03 Javascript
vue translate peoject实现在线翻译功能【新手必看】
Jun 07 Javascript
微信公众平台 客服接口发消息的实现代码(Java接口开发)
Apr 17 Javascript
微信小程序JS加载esmap地图的实例详解
Sep 04 Javascript
vue中音频wavesurfer.js的使用方法
Feb 20 Vue.js
使用JavaScript获取Django模板指定键值数据
May 27 Javascript
简单了解前端渐进式框架VUE
Jul 20 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字符串 ==比较运算符的副作用
2009/10/21 PHP
关于php mvc开发模式的感想
2011/06/28 PHP
浅析PHP原理之变量分离/引用(Variables Separation)
2013/08/09 PHP
Ajax+PHP实现的删除数据功能示例
2019/02/12 PHP
使用SMB共享来绕过php远程文件包含的限制执行RFI的利用
2019/05/31 PHP
PHP如何通过date() 函数格式化显示时间
2020/11/13 PHP
巧用jquery解决下拉菜单被Div遮挡的相关问题
2014/02/13 Javascript
js通过更改按钮的显示样式实现按钮的滑动效果
2014/04/23 Javascript
浅谈Javascript如何实现匀速运动
2014/12/19 Javascript
基于jquery插件实现拖拽删除图片功能
2020/08/27 Javascript
基于Bootstrap3表格插件和分页插件实例详解
2016/05/17 Javascript
检查表单元素的值是否为空的实例代码
2016/06/16 Javascript
D3.js实现雷达图的方法详解
2016/09/22 Javascript
Extjs gridpanel 中的checkbox(复选框)根据某行的条件不能选中的解决方法
2017/02/17 Javascript
基于bootstrap实现收缩导航条
2017/03/17 Javascript
详解JS中的柯里化(currying)
2017/08/17 Javascript
JavaScript使用FileReader实现图片上传预览效果
2020/03/27 Javascript
如何编写一个 Webpack Loader的实现
2020/10/18 Javascript
[12:29]《一刀刀一天》之DOTA全时刻19:蝙蝠骑士田伯光再度不举
2014/06/10 DOTA
比较详细Python正则表达式操作指南(re使用)
2008/09/06 Python
Python urlopen()函数 示例分享
2014/06/12 Python
python之import机制详解
2014/07/03 Python
Python中对列表排序实例
2015/01/04 Python
python web基础之加载静态文件实例
2018/03/20 Python
pandas的唯一值、值计数以及成员资格的示例
2018/07/25 Python
Python批量生成特定尺寸图片及图画任意文字的实例
2019/01/30 Python
class类在python中获取金融数据的实例方法
2020/12/10 Python
goodhealth官方海外旗舰店:新西兰国民营养师
2017/12/15 全球购物
事业单位个人应聘自荐信
2013/09/21 职场文书
机电一体化自荐信
2013/12/10 职场文书
预备党员党课思想汇报
2014/01/13 职场文书
幼儿园家长工作总结2015
2015/04/25 职场文书
学校安全管理制度
2015/08/06 职场文书
教你快速开启Apache SkyWalking的自监控
2021/04/25 Servers
MySQL中CURRENT_TIMESTAMP的使用方式
2021/11/27 MySQL
Axios代理配置及封装响应拦截处理方式
2022/04/07 Vue.js