setTimeout的若干坑
第一坑:作用域
首先,有一个关于this的面试题,是这样的:
var fullname = 'John Doe';
var obj = {
fullname: 'Colin Ihrig',
prop: {
fullname: 'Aurelio De Rosa',
getFullname: function() {
return this.fullname;
}
}
};
console.log(obj.prop.getFullname());
var test = obj.prop.getFullname;
console.log(test());
主要考察的是this的指向,很明显,this是根据上下文的执行环境决定的,obj.prop.getFullname()的上下文是obj.prop,而执行var test = obj.prop.getFullname,实际上是window.test = obj.prop.getFullname; 所以window.test()的this指向的是window,该题的结果为:先打印出Aurelio De Rosa,然后再打印出John Doe。但是,但问题还没有结束,变个形:
var fullname = 'John Doe';
var obj = {
fullname: 'Colin Ihrig',
prop: {
fullname: 'Aurelio De Rosa',
getFullname: function() {
setTimeout(function () {
console.log(this.fullname);
},100);
return this.fullname;
}
}
};
console.log(obj.prop.getFullname());
var test = obj.prop.getFullname;
console.log(test());
那现在呢,在setTimeout中会弹出什么?当时确实有那么几毫秒难住了我,一想,这个setTimeout,不就相当于window.setTimeout嘛,所以,setTimeout中的this依旧指向window,在setTimeout中console打印的结果为:John Doe。
第二坑:执行顺序
还是一个面试题,如下:
setTimeout(function(){ t = false; }, 1000);
while(true){}
alert('end');
问题来了:alert是否能够弹出?为什么?问题的答案是:不能弹出来,因为JS的单线程的,永远的单线程。在while(true)的时候陷入了死循环,就再先出不来了。关于JS的执行机制,请看这里:JavaScript 运行机制详解:再谈Event Loop这篇文章,已经很详细了,我就不多说了。
疑惑:时间点问题
然后,同事问了我个比较诡异的问题,如下:
console.log(1);
setTimeout(function() {
console.log('timeout invoke');
console.timeEnd('timeout');
}, 2000);
console.log(2);
console.time('hard');
console.time('timeout');
for (var i = 0;i<2000000000;i++) {}
console.timeEnd('hard');
console.log(3);
在chrome下,time的标志点hard的大概时间的13秒左右,那么问题来了,setTimeout的第二个参数若为2000(2秒),timeout这个时间为多少?如果为16000(16秒),时间为多少? 经过测试发现,如果这个setTimeout的时间设置为小于13秒,setTimeout会在console.log(3)后立即执行(与hard标志点间隔特别小),如果大于13秒,就在console.log(3)后的t-13秒后触发。 这就让我们很是疑惑,疑惑的点在于在浏览器内部。
- 是什么时候开始进行setTimeout的时间打点呢?
- JS是单线程的,是哪个线程打的点呢?
而经过测试发现,是在执行到setTimeout这句话的时候, 就已经打了点,如果回头执行队列的时间大于setTimeout设置的时间,就再等到了那个时间在触发setTimeout的回调, 如果小于setTimeout设置的时间,就立即执行(实际上已经延时太多了,这就是证明setTimeout不准的铁证,其实就算没有这种影响,也是不准的)。 具体可以参考这篇 JavaScript的单线程性质以及定时器的工作原理
但是第二个问题呢?我是这么想的:JS的单线程的,但是浏览器不是啊,所以是浏览器的另外一个线程负责的打点,如果您有不同的想法,请反馈给我吧,不胜感激。
最后
最近在研究一些原生JS的基础以及深入,发现真是路漫漫其修远兮,为自己加油!
setTimeout的若干坑的更多相关文章
- 微信小程序—setTimeOut定时器的坑
原文地址: http://fanjiajia.cn/2018/06/27/%E5%BE%AE%E4%BF%A1%E5%B0%8F%E7%A8%8B%E5%BA%8F%E2%80%94setTimeOu ...
- Linux:文件解压、复制和移动的若干坑
Linux下进行文件的解压.复制.移动应该是最常见的操作了.尤其是我们在项目中使用大量的数据集文件(比如机器学习)时.然而使用这些命令时一不留神就会掉进坑里,这篇文章我们就来细数用Shell进行文件操 ...
- geotrellis使用(二十四)将Geotrellis移植到CDH中必须要填的若干个坑
目录 前言 若干坑 总结 一.前言 近期干了一件事情,将geotrellis程序移植到CDH中(关于CDH,可以参考安装ClouderaManager以及使用ClouderaManage ...
- ulimit的坑
linux ulimit的若干坑 - ulimit真不是乱设的 原创 2016年11月16日 22:15:05 标签: linux 1997 soft和hard一起设置才好使 * soft nofil ...
- var 的一个坑,以及 let
选自 Typescript 中文教程. 快速的猜一下下面的代码会返回什么: for (var i = 0; i < 10; i++) { setTimeout(function() { cons ...
- 用python DIY一个图片转pdf工具并打包成exe
最近因为想要看漫画,无奈下载的漫画是jpg的格式,网上的转换器还没一个好用的,于是乎就打算用python自己DIY一下: 这里主要用了reportlab.开始打算随便写几行,结果为若干坑纠结了挺久,于 ...
- 用python读写excel(xlrd、xlwt)
最近需要从多个excel表里面用各种方式整理一些数据,虽然说原来用过java做这类事情,但是由于最近在学python,所以当然就决定用python尝试一下了.发现python果然简洁很多.这里简单记录 ...
- 继电器是如何成为CPU的(2)
继电器是如何成为CPU的(2) ——<穿越计算机的迷雾>整理和总结 上一篇已经从电池.开关.灯泡和继电器开始,画出了设计CPU所需的基本器件.这些器件将成为设计CPU的砖瓦木料.这一篇就用 ...
- 蓝鲸DevOps深度解析系列(2):蓝盾流水线初体验
关注嘉为科技,获取运维新知 前面一篇文章<蓝鲸DevOps深度解析系列(1):蓝盾平台总览>,我们总览了蓝鲸DevOps平台的背景.应用场景.特点和能力: 接下来我们继续解析蓝盾平台的 ...
随机推荐
- UIView--UIImageView
1.contentMode view.contentMode = UIViewContentModeScaleAspectFill; 2.是否实现触摸 3.简单实现动画 图片的名字为campFire0 ...
- [Effective Modern C++] Item 3. Understand decltype - 了解decltype
条款三 了解decltype 基础知识 提供一个变量或者表达式,decltype会返回其类型,但是返回的内容会使人感到奇怪. 以下是一些简单的推断类型: ; // decltype(i) -> ...
- WindowsAPI一日一练
1.SetWindowLong和GetWindowLong 函数原型: LONG SetWindowLong( __in HWND hWnd, __in int nIndex, __in LONG d ...
- OpenLayers 3加载本地Google切片地图
OpenLayers 提供了ol.source.XYZ 接口用以加载切片地图. 本地切片地图是用地图切片下载器下载的Google道路图层,由于软件未激活,所以每张切片地图上都有软件作者的联系方式,请 ...
- CKEditor扩展插件:自动排版功能
CKEditor是新一代的FCKeditor,是一个重新开发的版本.CKEditor是全球最优秀的网页在线文字编辑器之一,因其惊人的性能与可扩展性而广泛的被运用于各大网站. 如果还没接触过的可以看看, ...
- JavaEE Tutorials (25) - 使用Java EE拦截器
25.1拦截器概述380 25.1.1拦截器类381 25.1.2拦截器生命周期381 25.1.3拦截器和CDI38125.2使用拦截器381 25.2.1拦截方法调用382 25.2.2拦截生命周 ...
- Vis.js图表插件
Vis.js是一款基于JavaScript的可视化图表库,Vis.js不像其他的图表库那样仅仅支持几种常用的数据图表,比如线形图.柱状图.饼图等,Vis.js支持上百种不同类型的可视化图表类型,比如时 ...
- codeforces gym 100463I Yawner
//这题挂得让我怀疑我最近是不是做了什么坏事 题意:一个人有两个集合,先在其中一个集合选一个数x,然后向右走x布,然后再在另一个集合里选一个数y,向左走y步,问是否能走完数轴上所有点. 解:显然是求g ...
- POJ-1088 Skiing(记忆化搜索)
Description Michael喜欢滑雪百这并不奇怪, 因为滑雪的确很刺激.可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你.Michael想知道 ...
- 杭电oj 3079 Vowel Counting
Tips:可以先将输入的字符串全部转化为小写字母,然后再将元音字母变为大写,时间复杂度O(n) #include<stdio.h> #include<string.h> #in ...