第一坑:作用域

首先,有一个关于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的若干坑的更多相关文章

  1. 微信小程序—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 ...

  2. Linux:文件解压、复制和移动的若干坑

    Linux下进行文件的解压.复制.移动应该是最常见的操作了.尤其是我们在项目中使用大量的数据集文件(比如机器学习)时.然而使用这些命令时一不留神就会掉进坑里,这篇文章我们就来细数用Shell进行文件操 ...

  3. geotrellis使用(二十四)将Geotrellis移植到CDH中必须要填的若干个坑

    目录 前言 若干坑 总结 一.前言        近期干了一件事情,将geotrellis程序移植到CDH中(关于CDH,可以参考安装ClouderaManager以及使用ClouderaManage ...

  4. ulimit的坑

    linux ulimit的若干坑 - ulimit真不是乱设的 原创 2016年11月16日 22:15:05 标签: linux 1997 soft和hard一起设置才好使 * soft nofil ...

  5. var 的一个坑,以及 let

    选自 Typescript 中文教程. 快速的猜一下下面的代码会返回什么: for (var i = 0; i < 10; i++) { setTimeout(function() { cons ...

  6. 用python DIY一个图片转pdf工具并打包成exe

    最近因为想要看漫画,无奈下载的漫画是jpg的格式,网上的转换器还没一个好用的,于是乎就打算用python自己DIY一下: 这里主要用了reportlab.开始打算随便写几行,结果为若干坑纠结了挺久,于 ...

  7. 用python读写excel(xlrd、xlwt)

    最近需要从多个excel表里面用各种方式整理一些数据,虽然说原来用过java做这类事情,但是由于最近在学python,所以当然就决定用python尝试一下了.发现python果然简洁很多.这里简单记录 ...

  8. 继电器是如何成为CPU的(2)

    继电器是如何成为CPU的(2) ——<穿越计算机的迷雾>整理和总结 上一篇已经从电池.开关.灯泡和继电器开始,画出了设计CPU所需的基本器件.这些器件将成为设计CPU的砖瓦木料.这一篇就用 ...

  9. 蓝鲸DevOps深度解析系列(2):蓝盾流水线初体验

    关注嘉为科技,获取运维新知 前面一篇文章<蓝鲸DevOps深度解析系列(1):蓝盾平台总览>,我们总览了蓝鲸DevOps平台的背景.应用场景.特点和能力: ​ 接下来我们继续解析蓝盾平台的 ...

随机推荐

  1. JQ 更改li 颜色

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  2. 宏定义 define

    #define kOut -1 用一个字符串代替一个数据 用kOut表示-1(一般开头有一个小写的k) 作用: 1.为了让一些数据有意义 #define kUseId asdjlfdjafa #def ...

  3. 结构体 + typedef

    简单结构体 struct student{ char name[20];   //可以用scanf或者直接赋值 *如果用char *name  在用scanf时没有内存接收 long id; int ...

  4. [?]Unity快捷键

    Super=Win键. Rererence: What are Unity's keyboard and mouse shortcuts?

  5. jQuery + css 公告从左往右滚动

    $(function() { // 公告滚动 $(".notice-content").textScroll(); }); /** * 从右往左滚动文字 * @returns {u ...

  6. Android 开发使用lambda实现< JDK8兼容

    代码精简无疑是每个程序员的目标,简短易读.java 8中的lambda表达式的使用: 4 easy steps Download and install jdk8. Add the following ...

  7. windows 文件watch nodejs

    本篇博客,主要是记录下最近一直纠结的gulp.watch方法,在工作中我们肯定都遇到过,新添加的文件没办法自动触发watch,下面我们就来看有什么办法处理 1.首先我们肯定是先百度一下 百度推荐的是g ...

  8. 新测 thinkphp3.2 整合 PHPMailer 发送邮件

    PHPMailer 的官方网站:http://phpmailer.worxware.com/ PHPMailer 最新类库下载地址:[点击下载] PHPMailer GitHub 下载地址:https ...

  9. Python成长之路第二篇(3)_字典的置函数用法

    字典的置函数用法(字典dict字典中的key不可以重复) class dict(object): """ dict() -> new empty dictionar ...

  10. groovy 弹出菜单

    import groovy.swing.* import javax.swing.* import java.awt.* def swing = new SwingBuilder() swing.fr ...