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实现获取cookie过期时间的变通方法
Aug 14 Javascript
在Html中使用Requirejs进行模块化开发实例详解
Apr 15 Javascript
基于jquery实现三级下拉菜单
May 10 Javascript
Vue.js组件tree实现省市多级联动
Dec 02 Javascript
jQuery操作json常用方法示例
Jan 04 Javascript
简单易懂的天气插件(代码分享)
Feb 04 Javascript
vue+webpack实现异步加载三种用法示例详解
Apr 24 Javascript
vue-cli3全面配置详解
Nov 14 Javascript
使用vuepress搭建静态博客的示例代码
Feb 14 Javascript
jQuery实现的五星点评功能【案例】
Feb 18 jQuery
解决vue props传Array/Object类型值,子组件报错的情况
Nov 07 Javascript
JS前端使用canvas实现物体的点选示例
Aug 05 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中计算中文字符串长度、截取中文字符串的函数代码
2011/08/09 PHP
php操作JSON格式数据的实现代码
2011/12/24 PHP
php 操作数组(合并,拆分,追加,查找,删除等)
2012/07/20 PHP
php列出mysql表所有行和列的方法
2015/03/13 PHP
php实现向javascript传递数组的方法
2015/07/27 PHP
修改WordPress中文章编辑器的样式的方法详解
2015/12/15 PHP
JavaScript中几种常见排序算法小结
2011/02/22 Javascript
js操作CheckBoxList实现全选/反选(在客服端完成)
2013/02/02 Javascript
javascript和HTML5利用canvas构建猜牌游戏实现算法
2013/07/17 Javascript
浅析return false的正确使用
2013/11/04 Javascript
js不能获取隐藏的div的宽度只能先显示后获取
2014/09/04 Javascript
Js 正则表达式知识汇总
2014/12/02 Javascript
JavaScript中实现单体模式分享
2015/01/29 Javascript
javascript通过元素id和name直接取得元素的方法
2015/04/28 Javascript
JavaScript必知必会(五) eval 的使用
2016/06/08 Javascript
在js代码拼接dom对象到页面上去的模板总结(必看)
2017/02/14 Javascript
理解javascript async的用法
2017/08/22 Javascript
详解Javascript 中的 class、构造函数、工厂函数
2017/12/20 Javascript
vue的一个分页组件的示例代码
2017/12/25 Javascript
[54:53]2014 DOTA2国际邀请赛中国区预选赛 LGD-GAMING VS CIS 第二场
2014/05/23 DOTA
[05:06]2017亚洲邀请赛DAC回顾片
2017/04/19 DOTA
Python利用QQ邮箱发送邮件的实现方法(分享)
2017/06/09 Python
浅析PHP与Python进行数据交互
2018/05/15 Python
详解Python用户登录接口的方法
2019/04/17 Python
使用Python轻松完成垃圾分类(基于图像识别)
2019/07/09 Python
Python 给下载文件显示进度条和下载时间的实现
2020/04/02 Python
使用Python和百度语音识别生成视频字幕的实现
2020/04/09 Python
pyinstaller将含有多个py文件的python程序做成exe
2020/04/29 Python
Python3 pywin32模块安装的详细步骤
2020/05/26 Python
利用python批量爬取百度任意类别的图片的实现方法
2020/10/07 Python
管理岗位竞聘演讲稿
2014/08/18 职场文书
奉献爱心演讲稿
2014/09/04 职场文书
python控制台打印log输出重复的解决方法
2021/05/14 Python
http通过StreamingHttpResponse完成连续的数据传输长链接方式
2022/02/12 Python
浅析python中特殊文件和特殊函数
2022/02/24 Python
Spring Data JPA框架Repository自定义实现
2022/04/28 Java/Android