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 相关文章推荐
键盘KeyCode值列表汇总
Nov 26 Javascript
JavaScript实现的石头剪刀布游戏源码分享
Aug 22 Javascript
浅谈bootstrap源码分析之scrollspy(滚动侦听)
Jun 06 Javascript
详解Js模板引擎(TrimPath)
Nov 22 Javascript
解决拦截器对ajax请求的拦截实例详解
Dec 21 Javascript
Vue实现双向数据绑定
May 03 Javascript
node上的redis调用优化示例详解
Oct 30 Javascript
Vue.js的动态组件模板的实现
Nov 26 Javascript
15分钟学会vue项目改造成SSR(小白教程)
Dec 17 Javascript
详解Vue 单文件组件的三种写法
Feb 19 Javascript
jQuery实时统计输入框字数及限制
Jun 24 jQuery
解决vue里a标签值解析变量,跳转页面,前面加默认域名端口的问题
Jul 22 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
不用数据库的多用户文件自由上传投票系统(3)
2006/10/09 PHP
PHP与SQL语句常用大全
2016/12/10 PHP
Yii框架扩展CGridView增加导出CSV功能的方法
2017/05/24 PHP
Prototype 1.5.0_rc1 及 Prototype 1.5.0 Pre0小抄本
2006/09/22 Javascript
用js怎么把&字符换成"&amp:"
2006/10/19 Javascript
关于html+ashx开发中几个问题的解决方法
2011/07/18 Javascript
js 火狐下取本地路径实现思路
2013/04/02 Javascript
jqGrid表格应用之新增与删除数据附源码下载
2015/12/02 Javascript
不得不分享的JavaScript常用方法函数集(下)
2015/12/25 Javascript
jQuery Html控件基本操作(日常收集整理)
2016/03/11 Javascript
原生Javascript和jQuery做轮播图简单例子
2016/10/11 Javascript
JS用斜率判断鼠标进入DIV四个方向的方法
2016/11/07 Javascript
详解jQuery中的prop()使用方法
2020/01/05 jQuery
python进阶教程之循环对象
2014/08/30 Python
python执行外部程序的常用方法小结
2015/03/21 Python
Python Requests 基础入门
2016/04/07 Python
Python遍历文件夹和读写文件的实现代码
2016/08/28 Python
python3操作mysql数据库的方法
2017/06/23 Python
pandas 对series和dataframe进行排序的实例
2018/06/09 Python
解决python中使用plot画图,图不显示的问题
2018/07/04 Python
python实现图像外边界跟踪操作
2020/07/13 Python
Python 如何实现访问者模式
2020/07/28 Python
python切割图片的示例
2020/11/12 Python
python wsgiref源码解析
2021/02/06 Python
Html5 postMessage实现跨域消息传递
2016/03/11 HTML / CSS
html5实现移动端适配完美写法
2017/11/16 HTML / CSS
美国时装品牌:Nautica(诺帝卡)
2016/08/28 全球购物
香港优质食材和美酒专门店:FoodWise
2017/09/01 全球购物
进步之星获奖感言
2014/02/22 职场文书
我们的节日端午节活动方案
2014/03/02 职场文书
小学生演讲稿大全
2014/04/25 职场文书
群众路线剖析材料(四风)
2014/11/05 职场文书
行政后勤人员工作计划应该怎么写?
2019/08/16 职场文书
电子表的操作介绍说明书
2019/10/28 职场文书
对讲机的最大通讯距离是多少
2022/02/18 无线电
Golang获取List列表元素的四种方式
2022/04/20 Golang