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平台的背景.应用场景.特点和能力: 接下来我们继续解析蓝盾平台的 ...
随机推荐
- Method to fix "Naming information cannot be located because the target principal name is incorrect." for AD replication failure
Assume Failure DC FP01 and Working DC DC01 1. Stop the Key Distribution Center (KDC) service on FP01 ...
- HDU 5727 - Necklace
题意:( 0 <= n <= 9 ) 现在有n颗阴珠子和n颗阳珠子,将它们阴阳相间圆排列构成一个环, 已知有些阴珠子和阳珠子不能放在相邻的位置,否则这颗阳珠子就会失去功效, ...
- Lowest Common Ancestor of a Binary Search Tree、Lowest Common Ancestor of a Binary Search Tree
1.Lowest Common Ancestor of a Binary Search Tree Total Accepted: 42225 Total Submissions: 111243 Dif ...
- jquery widget开发——核心框架
框架代码: $.widget("myns.myplugin", { //默认参数 options: { }, //初始化,控件生命周期内只运行一次 _init: function ...
- URL 操作
1.$.param()将对象键值对转换为 URL 字符串键值对 var obj = { name : 'Lee', age : 100 }; alert($.param(obj));
- CSS发抖
纯CSS发抖 当您在 @keyframes 中创建动画时,请把它捆绑到某个选择器,否则不会产生动画效果. 通过规定至少以下两项 CSS3 动画属性,即可将动画绑定到选择器: 规定动画的名称 规定动画 ...
- paul的cnblog,欢迎大家的光临
我会在blog里面分享各种资源,技术文章,大家多多交流,欢迎拍砖.
- wampserver 2.2装好后80端口未被占用,却打不开localhost
在windows server 2003中装好wampserver2.2后打不开localhost,点击服务全部启动(颜色是橙色)也是打不开,我解决的原因是:安装mysql中sevice中的安装测试服 ...
- MySQL validate_password 插件
从创建用户说起: 如我们在mysql中可以用grant all on *.* to userd@'localhost' identified by '123'; 来创建一个userd用户,虽然用户是创 ...
- SQL Server dbcc checkdb 修复
默认dbcc checkdb 只做数据库的检测数据库是否完好.不会主动做数据库的修复,要修复数据库,需要数据库设单用模式. 1.repair_allow_data_loss 可能导致数据丢失. 2. ...