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 相关文章推荐
JavaScript 模拟类机制及私有变量的方法及思路
Jul 10 Javascript
ECMAScript5中的对象存取器属性:getter和setter介绍
Dec 08 Javascript
JS操作COOKIE实现备忘记录的方法
Apr 01 Javascript
AngularJS自定义插件实现网站用户引导功能示例
Nov 07 Javascript
解析利用javascript如何判断一个数为素数
Dec 08 Javascript
JS实现给json数组动态赋值的方法示例
Mar 19 Javascript
微信小程序实现tab切换效果
Nov 21 Javascript
详解Immutable及 React 中实践
Mar 01 Javascript
vue中倒计时组件的实例代码
Jul 06 Javascript
node和vue实现商城用户地址模块
Dec 05 Javascript
vue2.0实现的tab标签切换效果(内容可自定义)示例
Feb 11 Javascript
微信小程序实现上传多个文件 超过10个
Mar 30 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获取、检查类名、函数名、方法名的函数方法
2015/06/25 PHP
php集成开发环境详解
2019/09/24 PHP
S2SH整合JQuery+Ajax实现登录验证功能实现代码
2013/01/30 Javascript
js函数获取html中className所在的内容并去除标签
2013/09/08 Javascript
web css实现整站样式互相切换
2013/10/29 Javascript
抛弃Nginx使用nodejs做反向代理服务器
2014/07/17 NodeJs
JavaScript中的console.assert()函数介绍
2014/12/29 Javascript
js表格排序实例分析(支持int,float,date,string四种数据类型)
2015/05/06 Javascript
js实现带圆角的多级下拉菜单效果
2015/08/28 Javascript
超漂亮的Bootstrap 富文本编辑器summernote
2016/04/05 Javascript
Bootstrap富文本组件wysiwyg数据保存到mysql的方法
2016/05/09 Javascript
AngularJs bootstrap搭载前台框架——js控制部分
2016/09/01 Javascript
JavaScript之DOM插入更新删除_动力节点Java学院整理
2017/07/03 Javascript
vue生成token保存在客户端localStorage中的方法
2017/10/25 Javascript
JavaScript中Object值合并方法详解
2017/12/22 Javascript
微信小程序wepy框架笔记小结
2018/08/08 Javascript
快速解决angularJS中用post方法时后台拿不到值的问题
2018/08/14 Javascript
基于iview的router常用控制方式
2019/05/30 Javascript
微信公众号开发之微信支付代码记录的实现
2019/10/16 Javascript
Vue切换组件实现返回后不重置数据,保留历史设置操作
2020/07/21 Javascript
vue实现前端列表多条件筛选
2020/10/26 Javascript
js仿淘宝放大镜效果
2020/12/28 Javascript
Python 的类、继承和多态详解
2017/07/16 Python
Python使用django框架实现多人在线匿名聊天的小程序
2017/11/29 Python
python决策树之C4.5算法详解
2017/12/20 Python
Python参数解析模块sys、getopt、argparse使用与对比分析
2019/04/02 Python
python列表删除和多重循环退出原理详解
2020/03/26 Python
python属于解释语言吗
2020/06/11 Python
django前端页面下拉选择框默认值设置方式
2020/08/09 Python
Python urllib request模块发送请求实现过程解析
2020/12/10 Python
如何用border-image实现文字气泡边框的示例代码
2020/01/21 HTML / CSS
仿CSDN Blog返回页面顶部功能实现原理及代码
2013/06/30 HTML / CSS
Clarks英国官方网站:全球领军鞋履品牌
2016/11/26 全球购物
共产党员承诺书
2014/03/25 职场文书
mysql 获取相邻数据项
2022/05/11 MySQL