什么是DOM、BOM
BOM
BOM即浏览器对象模型,是在客户端脚本核心的基础上实现的扩展API,通过该API可以使用脚本访问浏览器窗口及其文档对象的各个方面。
Window对象其实是BOM中所有对象的核心对象,所有的对象都源自window对象,它表示整个浏览器出口。
在BOM API中,把WEB浏览器的各个主要外显特性、WEB页面及其标记、内容等都封装成一个对象,通过这些对象提供的成员访问窗口、文档、元素对象等,并在此基础上实现了对象的事件支持机制。所有BOM对象之间存在一定的关联关系。
学习BOM技术主要就是学习如何利用客户端脚本使用BOM对象,通过这些封装的BOM对象可实现很多DHTML功效。BOM技术不是标准化的WEB技术,因浏览器而异。 正因为如此大大限制了DHTML技术的应用领域与发展前景。不同浏览器实现的BOM技术并不统一,这是造成DHTML技术实现差异的主要原因,由此W3C在BOM技术的基础上进行扩充和完善、优化,制定了新的统一技术规范标准,即DOM文档对象模型技术。
DOM
DOM技术最初是针对XML文档的解析与控制而制定的技术规范,它可把HTML文档XML转化成XHTML文档,使用DOM技术来访问WEB页面文档中的各类对象。
DOM技术与XML技术密切相关,涉及的技术内容庞杂,学习难度较高,但掌握了BOM技术后再学习DOM技术有一定的帮助。
console.log('script start');
setTimeout(function() { console.log('setTimeout'); }, 0);
Promise.resolve().then(function() { console.log('promise1'); }).then(function() { console.log('promise2'); });
console.log('script end');
// 结果如下:
// script start
// script end
// promise1
// promise2
// setTimeout
任务队列
浏览器上下文中所有的任务可以分为同步任务和异步任务。
同步任务,顾名思义,就是立即执行的任务,同步任务一般会直接进入到主线程中执行 异步任务,就是异步执行的任务,比如ajax网络请求,setTimeout 定时函数等都属于异步任务,异步任务会通过任务队列( Event Queue )的机制来进行协调。 同步和异步任务分别进入不同的执行环境,同步的进入主线程,即主执行栈,异步的进入 Event Queue 。主线程内的任务执行完毕为空,会去 Event Queue 读取对应的任务,推入主线程执行。 上述过程的不断重复就是我们说的 Event Loop (事件循环)。
在事件循环中,每进行一次循环操作称为tick,通过阅读规范可知,每一次 tick 的任务处理模型是比较复杂的,其关键的步骤可以总结如下:
在此次 tick 中选择最先进入队列的任务( oldest task ),如果有则执行(一次) 检查是否存在 Microtasks ,如果存在则不停地执行,直至清空Microtask Queue 更新 render 主线程重复执行上述步骤
什么是闭包(closure)
闭包是一个受到保护的变量空间,由内嵌函数生成。JavaScript具有函数级的作用域。这意味着定义在函数内部的变量在函数外部不能被访问。JavaScript的作用域又是词法性质的。这意味着函数运行在定义它的作用域中,而不是调用它的作用域中。把这两个因素结合起来,就能通过把变量包裹在匿名函数中而对其加以保护。
各种专业文献的闭包定义都非常抽象,我的理解是: 闭包就是能够读取其他函数内部变量的函数。简单的闭包实现:
function foo(a) {
return function(b)
{
return a+b;
}
}
foo(1)(2) // 3
由于在javascript中,只有函数内部的子函数才能读取局部变量,所以说,闭包可以简单理解成定义在一个函数内部的函数。 所以,在本质上,闭包是将函数内部和函数外部连接起来的桥梁。
优点
逻辑连续,当闭包作为另一个函数调用的参数时,避免你脱离当前逻辑而单独编写额外逻辑。 方便调用上下文的局部变量。 加强封装性,第2点的延伸,可以达到对变量的保护作用。 缺点
闭包有一个非常严重的问题,那就是内存浪费问题,这个内存浪费不仅仅因为它常驻内存,更重要的是,对闭包的使用不当会造成无效内存的产生。