ECMAscript是JS的核心,而要在web上使用JS,那么BOM无疑是真正的核心。BOM叫浏览器对象模型,它提供了许多对象,用于访问浏览器的功能。

BOM的核心对象是window,它表示浏览器的一个实例。在浏览器中,它有双重角色,它既是通过JS访问浏览器的一个接口,又是ESMAScript规定的global对象。

1.全局作用域

在全局作用域中声明的变量,函数都会成为window对象的属性和方法。这里有一个小知识点:定义全局变量和在window对象上直接定义属性还是有点区别,全局变量不能通过delete操作直接删除,而直接在window对象上定义的属性可以删除。

使用var定义的window属性有一个名为(configurable)的特性,它的值设为false,所以不能删除。

2.间歇调用和超时调用

JS是单线程语言,浏览器无论在什么时候都只且只有一个线程在运行JavaScript程序,但它允许通过设置超时值和间歇值来调度代码在特定的时刻执行。

超时调用使用window对象的setTimeout方法,它接受两个参数:要执行的代码和以毫秒表示的时间。但是经过该时间指定的代码不一定执行。JS是一个单线程的解释器,一段时间只能执行一段代码,为了控制执行的代码,就有一个JS任务队列。

一段js代码(里面可能包含一些setTimeout、鼠标点击、ajax等事件),从上到下开始执行,遇到setTimeout、鼠标点击等事件,异步执行它们,此时并不会影响代码主体继续往下执行(当线程中没有执行任何同步代码的前提下才会执行异步代码),一旦异步事件执行完,回调函数返回,将它们按次序加到执行队列中,这时要注意了,如果主体代码没有执行完的话,是永远也不会触发callback的,如下例子:

 setTimeout(function() {
console.log('hello world');
}, 1000); while(true) {};

1s中之后,控制台并没有像预料中的一样输出字符串,而网页标签上的圈圈一直转啊转,掐指一算,可能陷入while(true){}的死循环中。

定时器仅仅是在未来的某个时刻将代码添加到代码队列中,执行时机是不能保证的。代码队列按照先进先出的原则在主进程空闲后将队列中的代码交给主线程运行。而定时器对队列的工作方式是,当特定的时间过去后将代码加入到队列中。设定一个150ms后执行的定时器不代表代码会在150ms之后执行,而是指代码会在150ms后加入到代码队列中。等到主进程空闲时并且该元素位于队列首位,其中的代码便会立即执行,看上去好像是在精确的时间点上执行了。实际上队列中的所有代码都要等到主进程空闲之后才能执行,而不管他们是怎样添加到队列中去的。

 var ele = document.getElementById('btn');
ele.onclick = function(){
setTimeout(function(){
document.getElementById(message).style.backgroundColor = "red";
}, 255);
var start = Date.now();
while(Date.now() - start <) {};
}

在这里Date.now()方法返回是从1970年1月1号到今天的毫秒数和(+new Date及 new Date中的getTime()方法相同)

以上示例中,定时器在255ms事被插入到代码队列中,但Javascript主线程有300ms处于运行状态,那么定时器代码至少要在定时器设置之后的300ms后才会被执行。以下时间线代表了上面代码的执行过程。

调用setTimeout()方法后,该方法会返回一个数值ID,表示超时调用。这个超时调用ID是计划执行的唯一代码,可以通过它来取消超时调用.

只要是在指定的时间还没有过去之前调用clearTimeout,就可以取消超时调用。

注意:

setInterval()方法

间隙调用和超时调用类似。只不过它会按照指定的时间重复执行代码,直至间隙调用被取消,或者页面被卸载。

为了确保定时器代码插入到队列总的最小间隔为指定时间。当使用setInterval()时,仅当没有该定时器的任何其他代码实例时,才能将定时器代码添加到代码队列中。假设没有这条原则,setInterval()创建的定时器确保了定时器代码能够规则的插入队列中。那么问题来了,假设Javascript主进程的运行时间非常长,那么setInterval的代码被多次添加到了代码队列中,等到主进程空闲时,定时器代码便会连续执行多次而之间不会有任何停顿。

  但是这条规则同样也带来了两个问题:

  1. 某些间隔会被跳过
  2. 多个定时器的代码执行之间的间隔可能会比预期的小(当前的setInterval回调正在执行,后一个添加)。

如下面代码:

 var ele = document.getElementById('btn');
ele.onclick = function(){
setInterval(function(){
    console.log('run interval');
var start = Date.now();
while(Date.now() - start <) {};
}, 200);
var start = Date.now();
while(Date.now() - start < 300) {};

上图中,第一个定时器在205ms出添加到队列中的,但是直到过了300ms才能够执行。当执行定时器代码时,在405ms时有一个定时器代码实例被添加到等待队列中。在605ms处第一个定时器代码仍然在运行,同时在代码队列中已经有了另一个定时器的代码实例。所以在这个605处的定时器代码不会被添加到队列中。结果在205ms处添加的定时器代码执行完毕后,405ms处添加的定时器代码会立即执行。

 为了避免setInterval的两个缺点,可以使用链式setTimeout():

setTimeout(function(){
//其他处理
setTimeout(arguments.callee, interval);
}, interval);

JS书上的实例,可以使用setTimeout来模拟setInterval()方法。

第八章—BOM(一)的更多相关文章

  1. js高级程序设计第八章BOM(未完成,待续)

    8.1window对象 BOM的核心对象是window,表示浏览器的一个实例. window对象有双重角色,既可以通过就是访问浏览器窗口的接口,又是ECMAscript规定的Global对象   8. ...

  2. 读书笔记 - js高级程序设计 - 第八章 BOM

      BOM的核心对象是window 它表示浏览器的一个实例,在浏览器中,window对象有双重角色,它既是通过js访问浏览器窗口的一个接口,又是ECMAScript规定的Global对象,这意味着在网 ...

  3. JavaScript高级程序设计学习笔记第八章--BOM

    1.间歇调用和超时调用: 超时调用:需要使用 window 对象的 setTimeout()方法,它接受两个参数:要执行的代码和以毫秒表示的时间(即在执行代码前需要等待多少毫秒).其中,第一个参数可以 ...

  4. 第8章BOM笔记

    第八章 BOM 一. Window 在浏览器中window有双重角色,他既是JavaScript访问浏览器窗口的一个借口,又是ECMAscript 规定的Global对象. 1.全局作用域 由于win ...

  5. 《JavaScript高级程序设计》笔记整理

    欢迎各位指导与讨论 : ) -------------------------待续------------------------------- 本文为笔者在学习时整理的笔记,如有错漏,恳请各位指出, ...

  6. js-JavaScript高级程序设计学习笔记6

    第八章 BOM 1.BOM的核心对象是window,他表示浏览器的一个实例.在浏览器中,window对象有双重角色,它既是通过JS访问浏览器窗口的一个接口,又是ES规定的Global对象. 2.定义全 ...

  7. JavaScript高级程序设计 读书笔记

    第一章 JavaScript 简介 第二章 Html中使用JavaScript 第三章 基本概念 第四章 变量,作用域,内存 第五章 引用类型 第六章 面向对象 第七章 函数表达式 第八章 BOM 第 ...

  8. 《JavaScript高级程序设计》 阅读计划

    第一周       第1章 JavaScript简介   1 第2章 在Html中使用JavaScript 1 第3章 基本概念   3         第二周       第4章 变量.作用域和内存 ...

  9. javaScript高程第三版读书笔记

    看完<dom编程艺术>现在准备读进阶版的js高程了,由于篇幅较长,所以利用刚看完<dom编程艺术>学到的知识写了段JavaScript代码,来折叠各章的内容.并且应用到了< ...

随机推荐

  1. 版本控制git之三-多人协作 变基 推送 拉取 删除远程分支

      版本控制git之三-多人协作 wangfeng7399已关注0人评论350人阅读2019-02-20 21:33:08   如果你想获得一份已经存在了的 Git 仓库的拷贝,比如说,你想为某个开源 ...

  2. PAT甲级——A1078 Hashing

    The task of this problem is simple: insert a sequence of distinct positive integers into a hash tabl ...

  3. 数据库insert和update

    1.当使用insert时不能使用where id=?,这是要使用update语句 2.只对一些列插入数据或者更新数据: insert是: insert tb(column1,column2..)val ...

  4. Python实例2-逗号代码

    假定有下面这样的列表: spam = ['apples', 'bananas', 'tofu', 'cats'] 编写一个函数,它以一个列表值作为参数,返回一个字符串.该字符串包含所有表项,表项之间以 ...

  5. iOS汇编系列-汇编入门

    概述 汇编语言(Assembly Language)用符号代替了0和1,比机器语言更便于阅读和记忆. 但是同样汇编语言同样指令太多不便于记忆,就出现了高级语言.C\C++\Java\Swift等,更接 ...

  6. Odoo 新 API 概述

    __all__ = [ 'Environment', 'Meta', 'guess', 'noguess', 'model', 'multi', 'one', 'cr', 'cr_context', ...

  7. Object源码阅读

    native修饰符:所修饰的方法的实现是由非java代码实现的 /** * 一个java程序如果想调用本地方法,需要执行两个步骤 * 1.通过system.loadLibrary()将包含本地方法实现 ...

  8. VS2015使用Nuget安装OpenCV3.X以及Python3安装OpenCV3.X

    VS2015已经自带Nuget安装工具了,所以,新建一个项目,点击管理Nuget包 搜索OpenCV3 注意,目前只有这个版本支持VS2015,也就是平台工具集可以为vs140,其他的都会报错,报错我 ...

  9. servlet接收request请求的json数据

    此次使用的是alibaba的fastjson:jar包为fastjson-1.2.7.jar 参考:https://www.qingtingip.com/h_229797.html 思路:由于此次接收 ...

  10. TZOJ 5094 Stringsobits(DP)

    描述 Consider an ordered set S of strings of N (1 <= N <= 31) bits. Bits, of course, are either ...