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 相关文章推荐
IE9+已经不对document.createElement向下兼容的解决方法
Sep 14 Javascript
整理Javascript函数学习笔记
Dec 01 Javascript
原生js编写焦点图效果
Dec 08 Javascript
Bootstrap CSS组件之面包屑导航(breadcrumb)
Dec 17 Javascript
javascript稀疏数组(sparse array)和密集数组用法分析
Dec 28 Javascript
微信JSAPI支付操作需要注意的细节
Jan 10 Javascript
jquery仿微信聊天界面
May 06 jQuery
了解VUE的render函数的使用
Jun 08 Javascript
vue使用自定义icon图标的方法
May 14 Javascript
create-react-app使用antd按需加载的样式无效问题的解决
Feb 26 Javascript
解决在Vue中使用axios用form表单出现的问题
Oct 30 Javascript
使用vant的地域控件追加全部选项
Nov 03 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
将RTF格式的文件转成HTML并在网页中显示的代码
2006/10/09 PHP
rephactor 优秀的PHP的重构工具
2011/06/09 PHP
PHP获取一个字符串中间一部分字符的方法
2014/08/19 PHP
PHP微信红包API接口
2015/12/05 PHP
PHP FileSystem 文件系统常用api整理总结
2019/07/12 PHP
cssQuery()的下载与使用方法
2007/01/12 Javascript
解析URI与URL之间的区别与联系
2013/11/22 Javascript
JS动态修改iframe高度和宽度的方法
2015/04/01 Javascript
一张Web前端的思维导图分享
2015/07/03 Javascript
jQuery打字效果实现方法(附demo源码下载)
2015/12/18 Javascript
js获取新浪天气接口的实现代码
2016/06/06 Javascript
jQuery焦点图轮播效果实现方法
2016/12/19 Javascript
jQuery实现圣诞节礼物传送(花式轮播)
2016/12/25 Javascript
Vue关于数据绑定出错解决办法
2017/05/15 Javascript
React-Native中禁用Navigator手势返回的示例代码
2017/09/09 Javascript
Bootstrap一款超好用的前端框架
2017/09/25 Javascript
React Native react-navigation 导航使用详解
2017/12/01 Javascript
用POSTMAN发送JSON格式的POST请求示例
2018/09/04 Javascript
NodeJS服务器实现gzip压缩的示例代码
2018/10/12 NodeJs
webpack4 SplitChunks实现代码分隔详解
2019/05/23 Javascript
Vue 中使用lodash对事件进行防抖和节流操作
2020/07/26 Javascript
prettier自动格式化去换行的实现代码
2020/08/25 Javascript
[05:10]2014DOTA2国际邀请赛 通往胜利之匙赛场探秘之旅
2014/07/18 DOTA
Python判断Abundant Number的方法
2015/06/15 Python
python快速建立超简单的web服务器的实现方法
2018/02/17 Python
详解flask入门模板引擎
2018/07/18 Python
python 有效的括号的实现代码示例
2019/11/11 Python
python正则过滤字母、中文、数字及特殊字符方法详解
2020/02/11 Python
Python基于爬虫实现全网搜索并下载音乐
2021/02/14 Python
CSS3 不定高宽垂直水平居中的几种方式
2020/03/26 HTML / CSS
梅西酒窖:Macy’s Wine Cellar
2018/01/07 全球购物
西班牙最大的婴儿用品网上商店:Bebitus
2019/05/30 全球购物
销售员岗位职责
2014/06/09 职场文书
学习十八大宣传标语
2014/10/09 职场文书
2015年医院药剂科工作总结
2015/05/04 职场文书
2019员工保密协议书(3篇)
2019/09/23 职场文书