浅谈箭头函数和setTimeout中的this
箭头函数会改变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的更多相关文章
- 浅谈javascript函数节流
浅谈javascript函数节流 什么是函数节流? 函数节流简单的来说就是不想让该函数在很短的时间内连续被调用,比如我们最常见的是窗口缩放的时候,经常会执行一些其他的操作函数,比如发一个ajax请求等 ...
- 浅谈Python在信息学竞赛中的运用及Python的基本用法
浅谈Python在信息学竞赛中的运用及Python的基本用法 前言 众所周知,Python是一种非常实用的语言.但是由于其运算时的低效和解释型编译,在信息学竞赛中并不用于完成算法程序.但正如LRJ在& ...
- 开发技术--浅谈Python函数
开发|浅谈Python函数 函数在实际使用中有很多不一样的小九九,我将从最基础的函数内容,延伸出函数的高级用法.此文非科普片~~ 前言 目前所有的文章思想格式都是:知识+情感. 知识:对于所有的知识点 ...
- 转:浅谈CSS在前端优化中一些值得注意的关键点
前端优化工作中要考虑的元素多种多样,而合理地使用CSS脚本可以在很大程度上优化页面的加载性能,以下我们就来浅谈CSS在前端优化中一些值得注意的关键点: 当谈到Web的“高性能”时,很多人想到的是页面加 ...
- 【WebApi系列】浅谈HTTP在WebApi开发中的运用
WebApi系列文章 [01]浅谈HTTP在WebApi开发中的运用 [02]聊聊WebApi体系结构 [03]详解WebApi参数的传递 [04]详解WebApi测试和PostMan [05]浅谈W ...
- [转载]浅谈JavaScript函数重载
原文地址:浅谈JavaScript函数重载 作者:ChessZhang 上个星期四下午,接到了网易的视频面试(前端实习生第二轮技术面试).面了一个多小时,自我感觉面试得很糟糕的,因为问到的很多问题都 ...
- 浅谈async函数await用法
今天状态不太好,睡久了懵一天. 以前只是了解过async函数,并还没有很熟练的运用过,所以先开个坑吧,以后再结合实际来更新下,可能说的有些问题希望大家指出. async和await相信大家应该不陌生, ...
- 浅谈JS函数防抖及应用场景
[前言] 在工作中,我们可能碰到这样的问题: 用户在搜索的时候,在不停敲字,如果每敲一个字我们就要调一次接口,接口调用太频繁,给卡住了. 用户在阅读文章的时候,我们需要监听用户滚动到了哪个标题,但是每 ...
- 浅谈JavaScript函数
JavaScript作为一种基于对象(非严格面向对象)的语言,函数在JS中的地位非同一般:用函数声明类和对象.甚至函数本身也是对象. 一.函数的三种声明方式辨析. 1.function命令 funct ...
随机推荐
- HashMap和Hashtable的比较
相同点 HashMap和Hashtable都是存储“键值对(key-value)”的散列表,而且都是采用拉链法解决hash冲突的.但是1.8中,hashmap引入了红黑树.Hashtable没有引入红 ...
- jq on方法绑定多个事件
一.jquery为多个选择器绑定同一个事件 $("#start,#end").on("click",function(){ alert("The pa ...
- requireJS的优化工具 ---- r.js
requireJS是javascript的模块加载器,是基于AMD规范实现的. r.js是其提供的对模块进行打包和构建的一个工具 下载 r.js 创建r.js 的配置文件 build.js build ...
- PWM----调节LED亮度
- - --调节两个LED灯亮度 module led_pwm ( clk, rst, //cnt1_pwm, out1, out2, out3, out4 ); input clk, rst; // ...
- IOS 集成友盟分享
#import <Foundation/Foundation.h> @interface UMSocialSinaHandler : NSObject +(void)openSSOWith ...
- windows 网络通讯模型Overlapped (转)(未看)
https://blog.csdn.net/jofranks/article/details/7895316 https://blog.csdn.net/caoshiying/article/deta ...
- bzoj2111 [ZJOI2010]排列计数
Description 称一个1,2,...,N的排列P1,P2...,Pn是Magic的,当且仅当2<=i<=N时,Pi>Pi/2. 计算1,2,...N的排列中有多少是Magic ...
- POJ Treasure Exploration 【DAG交叉最小路径覆盖】
传送门:http://poj.org/problem?id=2594 Treasure Exploration Time Limit: 6000MS Memory Limit: 65536K To ...
- Spring Boot 配置文件详解:Properties和YAML
一.配置文件的生效顺序,会对值进行覆盖: 1. @TestPropertySource 注解 2. 命令行参数 3. Java系统属性(System.getProperties()) 4. 操作系统环 ...
- html或jsp页面自动提交,无需每次重启服务
从eclipse转到idea遇到各种问题,之前eclipse可以自动保存页面内容无需重启服务,但是idea不可以,网上找了n种办法也没用,可能版本不一样吧,把我的解决方法纪录一下,方便以后有人遇到这个 ...