JavaScript是web前端开发的必备技能之一,在如今各种JS框架满天飞,我们如何选择并应用成了困扰,而且最头疼的是那么多浏览器与那么多的版本让应用的兼容性也成了前端的难题。本文是我对JS学习与工作使用的一个总结,从理论的角度剖析JS。
BOM(浏览器对象模型)
由于web开发中JS是运行在浏览器中的,而浏览器会提供一个API的形式让JS可以访问到一些属性,就样就产生了浏览器对象模型,包括窗口、访问记录、显示屏、浏览器、当前访问地址等相关信息,如下:
Window对象是JS中的顶级对象,window是其引用,JavaScript是一个纯粹的面向对象语言,在JS中一切皆对象,JS对象有一种专用的描述形式:JSON,JSON如今在其他语言中也变的通用了。window中对其他的BOM又有了引用,例如对Location的引用:window.location,如果我们想改变当前地址,只要给location的href重新赋值就可以了,因为location是Location的引用,而Location代表的就是当前访问地址。
Window对象
对于一个iframe其实也是一个window对象,而iframe的parent则是iframe外的窗口的引用,有关window的引用关系如图:
DOM(文档对象模型)
Document对象是窗口中的页面对象,在JS中对应成了文档,因为是XML的形式,Document对象其实是一棵树,里页包含了所有页面元素相关的,JS可以通过Document对象来操作页面,document是Document的引用,document是window的属性,所以可以通过window.document来访问对象的属性及方法。document里是一个个的element(元素),每个element又包含了很多attribute,每个attribute又包含了name和value。我们平常在页面上见到的a闭合标签、div闭合标签就是element对象,a标签里的href就是一个attribute,name是href,value就是URL。如图是Chrome43浏览器中从console中看的document对象:
一个element中包含了许多属性,如图是一个a标签里的一些属性:
Document的状态
浏览器在生成文档对象时会经过不同的状态,如图是我手动抓取的,但还有两个状态由于时间持续很短没能抓取到:
实际的状态流转是:
对于想要延迟加载的内容,可以通过监听document的状态变化来实现。
document的方法
目前比较流行的JS框架中的Jquery里的核心功能就是选择器,这些选择器是如何实现的呢,以jquery-1.8.2.js为例,我们看源码:
使用的document的getElementById的方法,由于ID是唯一的,所以这个方法查询的效率相对其他方法更快些,还有哪些方法?
getElementByClassName这个方法在IE8及以下是没有的,运行时你会发现如下的错误:
样式表
样式表在document里是什么样的呢?首先来看各元素是什么样子的吧:
可以看出一个很明显的树状结构,我们来看一下body的样式,其实是一个样式数组:
而这些样式名又对应规则树中具体的规则,样式规则树如图:
事件、作用域、闭包与事件传播机制
原生的事件是每个element里面的属性,如图是一个img元素的onerror属性,也就是图片下载失败的处理事件:
可以看到这个事件的处理函数的最下面有一个<function scope>,这是function的作用域链,里面包括了各个作用域,作用域其实也是对象,包括element对象,图中可以看出的作用域有img、window、document,还有一个Closure(闭包),Closure是JS中为了保证变量在其他地方引用时不被垃圾回收的一种机制,通常是一个function就是一个Closure。说到JS的对象回收机制,和引用有关,但也不是有引用了就不回收,例如孤岛对象,当然没被引用的是要回收的。
JS的事件传播机制:事件冒泡机制,如图:
子树结点上的事件会一直往上传播,除非我们用stopPropagation方法阻止不再传播,有这么个情况,如果在a标签绑定了某类型事件的处理,在父结点的div上又绑了一个同类型,如果在a上执行完不阻止的话,在div上就会又执行一次,造成了多次执行的后果。然而这种传播机制又有另一种好处,就是事件可以委托给上级处理,这样绑定事件处理函数时只需要绑定在上级对象上,新增子结点时事件的处理同样生效,就不用对新增的结点再绑定了,很多JS框架也是这么做的。
prototype
可以看到每个对象都有一个prototype属性,打开看下原来是指向父对象的,这其实是JS里的继承,而prototype其实是对父对象的引用。
MVVM
目前流行的JS框架越来越多,以选择器为核心的Jquery,还有根本看不到选择器的Angular,类似Angular的Avalon,Jquery就不多说了,来看下Angular吧,先看下在HTML怎么用的:
我框起来的部分其实在JS文件里都有对应的,这一个表单提交,如果用Jquery是会有用选择器的,但是在JS里却看不到选择器:
上手还是挺简单的,代码量也少,代码也比较清晰,也便于维护,类似的框架还有很多。
从我的角度来说,框架其实是一种工具,对于手机HTML5中我们还是要对框架的大小多慎重的,比如在手机上用Zepto肯定比用JQuery要好,Zepto兼容JQuery,但体积小很多,Zepto裁减了很多H5并不用的功能。
小结
往后发展,框架肯定是往更加精细的模块发展,拆的更多更具有针对性,用了才加载,更加轻量。