浅谈箭头函数和setTimeout中的this

时间:2022-04-27 04:08:59

箭头函数会改变this的指向,这个大家看文档都看到过,可是有没有具体理解呢?
我发现自己应该可能大概是......emmmm,然后我整理了一遍,加强一下概念吧
顺带再讲一下setTimeout这个函数改写this的概念

首先分别讲一下两位主角

  • 箭头函数:都2019年了,大家肯定不陌生了,用法很简单,可以自行百度,箭头函数有一个很大的特性是会改写内部的this指向,那么实际运用的过程中你考虑过注意过这个问题吗?箭头函数内部的this会指向声明箭头函数时所在作用域的this(划重点!!接下来要记住!)
  • setTimeout:大家肯定都用过了,它的第一个参数是一个方法,传入的这个方法内部的this会被改写指向window(划重点!!接下来要记住!)

一贯风格,我们上代码来看问题

// 先给window加一个id,以便于确认之后this的指向
window.id = 0;
// 声明一个函数fn
const fn = {
id: 1,
say: function() {
console.log('id:', this.id);
},
sayArrow: () => {
console.log('id:', this.id);
},
say1: function() {
setTimeout(function() {
console.log('id:', this.id);
}, 1000);
},
say2: function() {
let that = this;
setTimeout(function() {
console.log('id:', that.id);
}, 1000);
},
say3: function() {
setTimeout(() => {
console.log('id:', this.id);
}, 1000);
},
say4: () => {
setTimeout(() => {
console.log('id:', this.id);
}, 1000);
},
say5: () => {
setTimeout(function() {
console.log('id:', this.id);
}, 1000);
},
};

好了,接下来大家来做题,不要做晕了哈

fn.say();
fn.sayArrow();
setTimeout(fn.say, 1000);
setTimeout(fn.sayArrow, 1000);
setTimeout(() => fn.say(), 1000);
setTimeout(() => fn.sayArrow(), 1000);
fn.say1();
fn.say2();
fn.say3();
fn.say4();
fn.say5();

以上各自输出什么呢?接下来核对下答案,如果全对,那ojbk了
1 0 0 0 1 0 0 1 1 0 0
如果觉得自己可能没摸透,可以多包几层作用域再试试

接下来看代码讲原因!

fn.say();
/*
结果: 1
原因: 通过fn调用的say, say是 函数声明, this指向fn,输出的是fn.id
*/ fn.sayArrow();
/*
结果: 0
原因: 通过fn调用的say, say是 箭头函数声明, this指向箭头函数声明时作用域的this,也就是this指向window,输出的是window.id
*/ setTimeout(fn.say, 1000);
/*
结果: 0
原因: 通过setTimeout调用, setTimeout改写所传函数的this, 也就是this指向window,输出的是window.id
*/ setTimeout(fn.sayArrow, 1000);
/*
结果: 0
原因: 通过setTimeout调用, setTimeout改写所传函数的this, 也就是this指向window,输出的是window.id
*/ setTimeout(() => fn.say(), 1000);
/*
结果: 1
原因: 通过setTimeout调用, 但是fn.say()是被箭头函数包裹,所以fn.say()调用不受this改变的影响,原因参考第一句输出
ps: 等同于 setTimeout(function () { fn.say(); } , 1000);
*/ setTimeout(() => fn.sayArrow(), 1000);
/*
结果: 0
原因: 同上雷同,具体原因可参考第二句输出
ps: 等同于 setTimeout(function () { fn.sayArrow(); } , 1000);
*/ fn.say1();
/*
结果: 0
原因: setTimeout改写函数内部的this, 使其指向window, 输出window.id
*/ fn.say2(); //
/*
结果: 1
原因: setTimeout虽然改写函数内部的this,但是输出的是that.id,这个that在setTimout外面声明,指向的是fn,所以输出fn.id
*/ fn.say3(); //
/*
结果: 1
原因: fn.say3函数其内部的this指向的fn,而setTimeout内部传了一个箭头函数,箭头函数内部中的this就指向了fn.say3内的this,也就是fn,最后输出fn.id
*/ fn.say4(); //
/*
结果: 0
原因: fn.say4这个函数本身就是使用箭头函数声明,其内部的this指向的是箭头函数声明时所在的作用域,即window,而且setTimeout也是传了一个箭头函数,这里面的this指向外层箭头函数内部中的this,传引用也指向了window,最后输出window.id
*/ fn.say5(); //
/*
结果: 0
原因: fn.say5用箭头函数声明,其内部的this指向window,而且setTimeout也会改写内部this指向window,最后输出window.id
*/

其实有一些调用其根本原因是相同的,但是我个人喜欢各个方面去验证一下,加深一下印象也好,勿喷
附带说一嘴,如果有同学在学node, node内部是没有window对象的,window是浏览器规范,所以具体情况看你在哪里用了,不过概念是差不多的

写完觉得这篇文章真的是浅谈...好low啊哈哈哈哈,写给自己看!

浅谈箭头函数和setTimeout中的this的更多相关文章

  1. 浅谈javascript函数节流

    浅谈javascript函数节流 什么是函数节流? 函数节流简单的来说就是不想让该函数在很短的时间内连续被调用,比如我们最常见的是窗口缩放的时候,经常会执行一些其他的操作函数,比如发一个ajax请求等 ...

  2. 浅谈Python在信息学竞赛中的运用及Python的基本用法

    浅谈Python在信息学竞赛中的运用及Python的基本用法 前言 众所周知,Python是一种非常实用的语言.但是由于其运算时的低效和解释型编译,在信息学竞赛中并不用于完成算法程序.但正如LRJ在& ...

  3. 开发技术--浅谈Python函数

    开发|浅谈Python函数 函数在实际使用中有很多不一样的小九九,我将从最基础的函数内容,延伸出函数的高级用法.此文非科普片~~ 前言 目前所有的文章思想格式都是:知识+情感. 知识:对于所有的知识点 ...

  4. 转:浅谈CSS在前端优化中一些值得注意的关键点

    前端优化工作中要考虑的元素多种多样,而合理地使用CSS脚本可以在很大程度上优化页面的加载性能,以下我们就来浅谈CSS在前端优化中一些值得注意的关键点: 当谈到Web的“高性能”时,很多人想到的是页面加 ...

  5. 【WebApi系列】浅谈HTTP在WebApi开发中的运用

    WebApi系列文章 [01]浅谈HTTP在WebApi开发中的运用 [02]聊聊WebApi体系结构 [03]详解WebApi参数的传递 [04]详解WebApi测试和PostMan [05]浅谈W ...

  6. [转载]浅谈JavaScript函数重载

     原文地址:浅谈JavaScript函数重载 作者:ChessZhang 上个星期四下午,接到了网易的视频面试(前端实习生第二轮技术面试).面了一个多小时,自我感觉面试得很糟糕的,因为问到的很多问题都 ...

  7. 浅谈async函数await用法

    今天状态不太好,睡久了懵一天. 以前只是了解过async函数,并还没有很熟练的运用过,所以先开个坑吧,以后再结合实际来更新下,可能说的有些问题希望大家指出. async和await相信大家应该不陌生, ...

  8. 浅谈JS函数防抖及应用场景

    [前言] 在工作中,我们可能碰到这样的问题: 用户在搜索的时候,在不停敲字,如果每敲一个字我们就要调一次接口,接口调用太频繁,给卡住了. 用户在阅读文章的时候,我们需要监听用户滚动到了哪个标题,但是每 ...

  9. 浅谈JavaScript函数

    JavaScript作为一种基于对象(非严格面向对象)的语言,函数在JS中的地位非同一般:用函数声明类和对象.甚至函数本身也是对象. 一.函数的三种声明方式辨析. 1.function命令 funct ...

随机推荐

  1. JS js与css的动态加载

    http://www.cnblogs.com/zhuimengdeyuanyuan/archive/2013/03/06/2946277.html

  2. matlab print,disp,fprint,fscan

    http://wenku.baidu.com/link?url=ZvpdbnbozLtaSQA011ZBl5tbpqN62nu8VH-sBZYDQkv4KaaIwnaSXg5vPDgxTjudG-Qn ...

  3. 【算法】一般冒泡排序 O(n^2) 稳定的 C语言

    冒泡排序 一.算法描述 假设序列中有N个元素: 第一趟选取第一个元素作为关键字,从左至右比较,若遇到比它小的则放到它左边(也即两数进行交换),若遇到比它大的,则改为选取该元素作为关键字完成后续的比较, ...

  4. iPhoneKeyboard

    iPhoneKeyboard.Open static function Open (text : string, keyboardType : iPhoneKeyboardType = iPhoneK ...

  5. JSON.parse()的异常怎么处理;

    <!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. vue-loader的理解

    1.vue-loader是webpack的加载器,允许以单文件组件(SFC)的格式创作Vue组件 2.允许对Vue组件的每个部分使用其他webpack加载器 3.允许.vue文件中的自定义块可以应用自 ...

  7. 14、Spark的核心术语

    Application:spark应用程序,就是用户基于spark api开发的程序,一定是通过一个有main方法的类执行的,比如java开发spark,就是在eclipse中,建立的一个工程 App ...

  8. 【转】CentOS 7&period;X 系统安装及优化

    [转]CentOS 7.X 系统安装及优化 centos的演变 启动流程sysvinit 串行启动:一次一个,一个一个启动 并行启动:全部的一起启动 init优点 运行非常良好.主要依赖于shell脚 ...

  9. vue2之对象属性的监听

    对象属性监听的两种方法: 1.普通的watch data() { return { frontPoints: 0 } }, watch: { frontPoints(newValue, oldValu ...

  10. 使用tableau去将存入mysql都地区点击率进行了展示 感觉很好用

    1.连接数据源很多选项:hive mysql Oracle 等所有数据库 2.写上hive2的那个客户端连接,下边会显示出让我装连接的驱动 ,所有jdbc都需要这样 点进去找到windows的下载一键 ...