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 相关文章推荐
angular.foreach 循环方法使用指南
Jan 06 Javascript
js倒计时简单实现代码
Aug 11 Javascript
JS简单实现tab切换效果的多窗口显示功能
Sep 07 Javascript
JS两种类型的表单提交方法实例分析
Nov 28 Javascript
Ajax 加载数据 练习代码
Jan 05 Javascript
javaScript基础详解
Jan 19 Javascript
基于Particles.js制作超炫粒子动态背景效果(仿知乎)
Sep 13 Javascript
收集前端面试题之url、href、src
Mar 22 Javascript
vue中引用swiper轮播插件的教程详解
Aug 16 Javascript
Vue 莹石摄像头直播视频实例代码
Aug 31 Javascript
Vue 开发必须知道的36个技巧(小结)
Oct 09 Javascript
jQuery/JS监听input输入框值变化实例
Oct 17 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
php抓即时股票信息
2006/10/09 PHP
require(),include(),require_once()和include_once()区别
2008/03/27 PHP
php magic_quotes_gpc的一点认识与分析
2008/08/18 PHP
简单的php写入数据库类代码分享
2011/07/26 PHP
zend Framework中的Layout(模块化得布局)详解
2013/06/28 PHP
php中的静态变量的基本用法
2014/03/20 PHP
php+ajax实现无刷新分页的方法
2014/11/04 PHP
php获取twitter最新消息的方法
2015/04/14 PHP
php实现读取和写入tab分割的文件
2015/06/01 PHP
PHP整合PayPal支付
2015/06/11 PHP
一个可拖拽列宽表格实例演示
2012/11/26 Javascript
javascript错误的认识不用关心内存管理
2012/12/15 Javascript
javascript回车完美实现tab切换功能
2014/03/13 Javascript
jquery.cookie.js使用指南
2015/01/05 Javascript
论JavaScript模块化编程
2016/03/07 Javascript
bootstrap常用组件之头部导航实现代码
2017/04/20 Javascript
详谈for循环里面的break和continue语句
2017/07/20 Javascript
深入理解Node内建模块和对象
2019/03/12 Javascript
[02:20]DOTA2亚洲邀请赛 IG战队出场宣传片
2015/02/07 DOTA
全面了解Python环境配置及项目建立
2016/06/30 Python
node.js获取参数的常用方法(总结)
2017/05/29 Python
Python用imghdr模块识别图片格式实例解析
2018/01/11 Python
把pandas转换int型为str型的方法
2019/01/29 Python
Pytorch在NLP中的简单应用详解
2020/01/08 Python
美国户外烹饪产品购物网站:Outdoor Cooking
2020/01/10 全球购物
怎样自定义一个异常类
2016/09/27 面试题
记帐员岗位责任制
2014/02/08 职场文书
文明生主要事迹
2014/05/25 职场文书
基层党组织建设整改方案
2014/09/16 职场文书
2014学校领导四风对照检查材料思想汇报
2014/09/23 职场文书
交通事故委托书范本
2014/09/28 职场文书
2014年科技工作总结
2014/11/26 职场文书
校长新学期致辞
2015/07/30 职场文书
交通安全教育心得体会
2016/01/15 职场文书
导游词之广州陈家祠
2019/10/21 职场文书
Windows下使用Nginx+Tomcat做负载均衡的完整步骤
2021/03/31 Servers