setTimeout 的定义域问题

记旧项目 TypeScript 改造问题与解决方案 概述 由于本次改造的项目为一个通过NPM进行发布的基础服务包,因此本次采用TypeScript进行改造的目标是移除Babel全家桶,减小包体积,同时增加强类型约束从而避免今后开发时可能的问题。 本次改造使用的是TypeScript v2.9.2,采用Webpack v4.16.0进行打包编译。开发工具使用的是VSCode,使用中文语言包。预期目标是直接将TypeScript代码通过loader直接编译为ES5的代码。 本文中涉及的问题有部分是TypeScript配置和使用的问题,也有部分是VSCode 阅读详情

转载文章,记作学习

https://www.cnblogs.com/oxspirt/p/7659830.html

问题描述

前些天在练习写一个小例子的时候用到了定时器,发现在setInterval和setTimeout中传入函数时,函数中的this会指向window对象,如下例:

var num = 0;
function Obj (){
    this.num = 1,
    this.getNum = function(){
        console.log(this.num);
    },
    this.getNumLater = function(){
        setTimeout(function(){
            console.log(this.num);
        }, 1000)
    }
}
var obj = new Obj; 
obj.getNum();//1  打印的是obj.num,值为1
obj.getNumLater()//0  打印的是window.num,值为0

问题原因

从上述例子中可以看到setTimeout中函数内的this是指向了window对象,这是由于setTimeout()调用的代码运行在与所在函数完全分离的执行环境上。这会导致这些代码中包含的 this 关键字会指向 window (或全局)对象。详细可参考MDN setTimeout

解决方法

若想要让setTimeout中的this指向正确的值,可以使用以下三种比较常用的方法来使this指向正确的值:

1.将当前对象的this存为一个变量,定时器内的函数利用闭包来访问这个变量,如下:

var num = 0;
function Obj (){
    var that = this;    //将this存为一个变量,此时的this指向obj
    this.num = 1,
    this.getNum = function(){
        console.log(this.num);
    },
    this.getNumLater = function(){
        setTimeout(function(){
            console.log(that.num);    //利用闭包访问that,that是一个指向obj的指针
        }, 1000)
    }
}
var obj = new Obj; 
obj.getNum();//1  打印的是obj.num,值为1
obj.getNumLater()//1  打印的是obj.num,值为1

这种方法是将当前对象的引用放在一个变量里,定时器内部的函数来访问到这个变量,自然就可以得到当前的对象。

2.利用bind()方法

var num = 0;
function Obj (){
    this.num = 1,
    this.getNum = function(){
        console.log(this.num);
    },
    this.getNumLater = function(){
        setTimeout(function(){
            console.log(this.num);
        }.bind(this), 1000)    //利用bind()将this绑定到这个函数上
    }
}
var obj = new Obj; 
obj.getNum();//1  打印的为obj.num,值为1
obj.getNumLater()//1  打印的为obj.num,值为1

bind()方法是在Function.prototype上的一个方法,当被绑定函数执行时,bind方法会创建一个新函数,并将第一个参数作为新函数运行时的this。在这个例子中,在调用setTimeout中的函数时,bind方法创建了一个新的函数,并将this传进新的函数,执行的结果也就是正确的了。关于bind方法可参考 MDN bind

3. 箭头函数

var num = 0;
function Obj (){
    this.num = 1,
    this.getNum = function(){
        console.log(this.num);
    },
    this.getNumLater = function(){
        setTimeout(() => {
            console.log(this.num);
        }, 1000)    //箭头函数中的this总是指向外层调用者,也就是Obj
    }
}
var obj = new Obj; 
obj.getNum();//1  打印的是obj.num,值为1
obj.getNumLater()//1  打印的是obj.num,值为1


ES6中的箭头函数完全修复了this的指向,this总是指向词法作用域,也就是外层调用者obj,因此利用箭头函数就可以轻松解决这个问题。

以上三种方法都是比较常用的,当然如果使用call或apply方法来代替bind方法,得到的结果也是正确的,但是call方法会在调用之后立即执行,那样也就没有了延时的效果,定时器也就没有用了,所以推荐使用上述方法来将this传进setTimeout和setInterval中。 

编程函数与数学函数的本质区别:从映射关系到执行单元 函数是编程与数学中的核心概念,它本质上描述了一种输入与输出之间的映射关系。在数学中,函数是确定性的、无副作用的映射规则,如 f(x)=x²。而在计算机科学中,函数演变为封装可复用行为的执行单元,其核心价值在于实现代码复用与逻辑抽象,并能通过副作用(如修改状态、进行IO操作)与现实世界交互。这一范式扩展使得函数成为构建现代软件的基础模块,广泛应用于数据处理、业务逻辑封装和系统调用等场景。理解纯函数与高阶函数等概念,有助于编写更可预测、易测试的代码,是提升工程实践能力的关键。 阅读详情

相关推荐

模糊高清修复真王炸!ComfyUI-SeedVR2-Kontext(画质修复+P图)本地部署教程

SeedVR2_comfyUI 是由字节跳动 Seed 实验室与南洋理工大学 S-Lab 联合开源的,专为 ComfyUI 用户开发的插件版本,官方项目名为。它主打,在图像超分上表现尤其亮眼,被多位实测者称为“目前模糊图像修复最强模型“。SeedVR2 在图像超分任务中表现突出,尤其擅长恢复模糊图像的细节,被称为“模糊高清修复真王炸”。特别的,也适合用于文字密集图像(如截图、扫描文档、老照片字幕)修复。模型通过对抗训练 + 特征匹配损失提升细节真实感,理论上对文字边缘锐化也有帮助。

SJJS_1的博客 2686

setTimeout里的this具体指向?

现代浏览器的设计是以用户体验为首要原则的,因此,一些浏览器可能会忽视 autocomplete="off"的设置,以保持用户输入信息的便利性,特别是对于用户名和密码的输入框。这对于用户来说是一个便捷的功能,但对开发者来说可能会带来一些不便。2.使用一个比较常见但有些hack的方法,即在你的真正输入框前,添加一个隐藏的假输入框。浏览器通常会自动填充第一个找到的输入框,因此它会将自动填充应用于隐藏的假输入框。例如,你可以监听页面加载完成的事件,然后用JavaScript清空输入框。

aoteman2135的博客 1184

ENVI5.6 Seamless Mosaic多景影像镶嵌色差问题

多景影像无缝镶嵌色差问题拟解决方法

Matchaya的博客 7705

angular8入门

一:开发环境准备 下载安装angular Node.js,webpack,脚手架搭建 查看node版本:node –v Angular8只支持node10以上版本 查看npm版本:npm –v 删除已安装的旧版本的angular:cnpm uninstall –g @angular/cli 删除angular安装包 清除缓存:npm cache clean --force 全局安...

jenniferzgh的博客 1327

C#实战:如何从零构建一个轻量级软PLC梯形图编辑器(附完整源码)

本文详细介绍了如何使用C#从零开始构建一个轻量级软PLC梯形图编辑器。内容涵盖项目架构设计、GDI+图形渲染、编辑交互实现以及核心的扫描执行引擎开发,并提供了定时器、计数器等高级功能的实现思路与完整源码,为开发者深入工业自动化领域提供了实战指南。

4k5l6j7h8的博客 258

不只是对齐:用 MFA 和 Praat 给你的语音数据集快速生成 TextGrid 标注文件

本文详细介绍了如何利用Montreal Forced Aligner(MFA)和Praat工具快速生成TextGrid标注文件,大幅提升语音数据标注效率。通过批量对齐、质量校验和跨语言处理等实战技巧,帮助研究者构建自动化标注流水线,适用于语音合成和语音识别等多种应用场景。

weixin_30675247的博客 378

关于typescript的定时器setInterval()坑

最近帮公司的APP前端做RN,要求是用typescript,然后就掉进坑里了,别的不说,先说说setInterval()这个定时器函数,因为typescript是强类型语言,定义setInterval()必须定义其返回值,但是你无论用百度或者谷歌搜中文也好英文也罢,都告诉你setInterval()的返回值类型是number,但是真的是这样么?让我们看看 如果你将setInterval()定...

ollin2012的博客 2万+

微信公众号 - 解决报错 “err_msg“:“system:access_denied“,微信环境浏览器真机使用微信支付、微信授权登录、分享朋友圈转发好友报错system:access_denied

微信公众号,微信网页,手机h5网页,微信报错,system:access_denied,微信支付,提示报错,微信登录授权报错,微信朋友圈分享,微信转发,WeixinJSBridge,微信环境下,微信内置浏览器,微信公众号项目报错system:access_denied,如何解决,invoke(),API调用后出现报错,微信内部H5 WeixinJSBridge.invoke system:access_denied,使用微信jssdk时报access_denied错误,还是报错,真机运行,真机调试api返回

🏆 前端领域优质创作者 1万+

angular4使用错误问题汇总

1.问题:无法在指定目录下创建组件    错误信息:Path “” must be absolute    解决:   原启动命令:    (1)cnpm install     (2)cnpm install primeng@4.2.2    (3)cnpm install @angular/cli@1.6.3      (4)cnpm install @an

杜 976

fasterlio原理及代码框架梳理

Faster-LIO 的优势是在保持同等高精度的前提下,显著提升计算效率,以支持更极端的应用场景(如高速无人机)和更廉价的硬件平台。可以把 Faster-LIO 理解为用一把更快的“空间哈希筛子”(iVox)替换了原来精细的“动态平衡树”(ikd-Tree),从而在精度损失极小的情况下,实现了效率的显著提升。:只在实际有地图点的空间区域动态创建和保留体素单元,形成一个稀疏的体素地图。是关键:将去畸变点云中的每个点,在 iVox 维护的局部地图中搜索近邻(如5个最近点),构建点到面的距离残差。

Studying…… 246

【软件系统架构】系列四:嵌入式技术

嵌入式系统是以应用为中心、以计算机技术为基础,并将可配置与可裁剪的软硬件集成于一体的专用计算机系统。它需要满足功能、可靠性、成本、体积、功耗等方面的严格要求。 嵌入式系统一般由以下组成部分构成:

moton2017的博客 1001

箭头函数的this指向及注意事项

今天来说一说箭头函数的this指向。 箭头函数( =>)是ES6新特性,它的作用不应该仅仅是缩减代码那么简单,更重要的是它改变了this的指向。 首先来说说箭头函数中用this后,this的指向。依照我个人的理解,箭头函数没有自己的this,它的this会捕获其定义时所在的定义域中的this作为自己的this 例子1: var obj = { a : 1, b : () => { ...

Chic_Chen的博客 1620

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

关于setInterval和setTImeout中的this指向问题

问题:setInterval和setTimeout中传入函数时,函数中的this会指向window对象 我们先来看一个例子: var num = 0; function Obj (){ this.num = 1, this.getNum = function(){ console.log(this.num); }, this.getNumLater = function(){ setTimeout(function(){

wzg0817的博客 307

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

前端读者 | 由setTimeout引发的JS引擎运行机制的研究

本文来自 @xiaoyuze88 链接:http://xiaoyuze88.github.io/ 太久没碰代码了,那天想到关于循环调用setTimeout实现每隔一秒输出递增的数的那个问题,搞了搞,发现很多概念模糊了,在此总结下。 所谓的循环调用setTimeout实现递增输出,就是说用for循环10次,每隔一秒输出一个从0~9的数。 不多说,直接上最终代码再说,细节后面再谈。 for (va...

weixin_30780221的博客 122

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

JavaScript闭包

我的总结就是, 当一个函数离开了它定义块,而在定义域外部被调用,便形成了一个闭包.

no ACMer 532

一段程序让你看懂JS中的this

看下面这段程序 var name = "Bob"; var nameObj ={ name : "Tom", showName : function(){ console.log(this.name); }, waitShowName : fu...

weixin_34417183的博客 79

BOM部分

上面那个是会等页面都加载完了,在进行函数的调用或者触发事件,如(图像,文本,css,js等),所以那个声明可以写在所属标签的前面第一个,传统注册页面只能写一次,如果有多个,则会以最后一个为准使用监听器还是对个数没有限制。

2301_80339466的博客 426

5.深入理解箭头函数 - JS

根据具体案例的分析,深入理解 JS 的箭头函数,以及因为 this 绑定产生的一系列问题。

wander_alice的博客 1133

编写高效 JavaScript动画 使用定时器技巧和圆周运动

在使用定时器时,需要注意性能和用户体验。过多或过频的定时器任务可能会影响网页性能,而过长的定时器延时可能会导致用户等待时间过长。定时器:JavaScript 提供了两个定时器函数:setTimeout 和 setInterval。通过设置定时器,可以在指定的时间间隔执行代码来创建动画效果。它接受两个参数:要执行的代码和时间间隔(以毫秒为单位)。1、setTimeout: setTimeout函数用于在指定的时间后执行一次代码。它接受两个参数:要执行的代码和延时的时间(以毫秒为单位)。

likeJava76的博客 189

js 事件流程

js 事件流程

神膘护体小月半的博客 726

JavaScript

函数 1. ➕号或减号在后边先赋值后自➕或自➖ 外循环是行数,内循环是列数 2. onclick时间会在被点击时发生 3. (1)声明参数不能加var (2)函数使用function关键字来定义,有函数声明和函数表达式两种形式 (3)函数中我们可以通过关键字return返回函数的结果 (4)函数的参数分为形参和实参,可以向函数传入任意数量的实参,并且可以通过arguments对象访问这些实参 (5)函数的调用是函数名后紧跟一对小括号,需要传参时,传入相应的参数即可 4. 函数定义 5

weixin_71819778的博客 242

函数本质解析:从数学映射到编程实践的核心概念辨析

函数是计算机科学中的基础概念,本质上是输入到输出的确定性映射关系。在编程中,函数作为封装可调用代码单元,实现了逻辑抽象与复用,是构建模块化软件的核心。其技术价值在于提升代码的可读性、可维护性,并支撑了函数式编程、事件驱动等高阶范式。无论是Python中的`upper()`方法,还是JavaScript的箭头函数,都体现了这一核心机制。理解函数的本质有助于避免常见混淆,例如将C语言中的宏或仅有副作用的`print()`调用误判为纯函数。掌握函数判断标准,是编写优雅、高效代码,并深入理解闭包、回调等高级特性的关

weixin_33851429的博客 320

js深入系列-函数

子程序 一个或者多个语句组成的完成特定任务的相对独立的的一段代码块; 包括: 函数: 有返回值 方法: 在对象中 过程: 没有返回值 数学中函数 定义域中每一项元素总会对应一个或者多个值域中的值。 -函数式编程 编程风格符合数学函数; 闭包与let for(let i =0;i<6;i++){ setTimeout(() => { console.log(i) }) // ...

wang_liuyong的博客 229

javascript的BOM

BOM window对象是BOM的顶层对象 location对象 history对象 document对象 window对象的属性的属性和方法 window.screen.width:屏幕分辨率的宽度 window.screen.height:屏幕分辨率的高度 document.documentElement.clientWidth:获取浏览器当前的宽度 document.doc...

119

别再只会送礼物了!用这个开源网页项目给你的TA一个程序员式的浪漫惊喜

本文教你如何用HTML、CSS和JS打造一个专属的互动表白网页,为TA带来程序员式的浪漫惊喜。从项目构思到技术实现,详细介绍了源码修改教程和核心功能开发,帮助你将情感与技术完美结合,创造独特的数字礼物。

weixin_30460489的博客 394
上一篇: JavaScript高级程序设计 笔记【第五章】function类型
下一篇: 【第三章—快速入门】《node.js开发指南》读书笔记
崔佳宇_
崔佳宇_ 优质创作者: 嵌入式与硬件开发技术领域 优质创作者: 嵌入式与硬件开发技术领域
博客等级 码龄10年 1万+粉丝 173原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值