理解前端(HTML、JavaScript、Css)
javascript具备了与浏览器窗口(Bom)及其内容(HTML)等几乎所有方面交互的能力。要想全面理解和掌握javascript,关键在于弄清楚它的本质、历史和局限性。Web是网站的意思,网站有很多网页,网页就是前端写的,前端分为HTML、CSS、JavaScript,HTML定义网页的结构,css描述网页的样子,javascript设置网页的行为。后端主要用来存储数据的,前端和后端利用http来实现通信,获取后端数据库里的数据显示在页面上。
ECMAScript将后端所有数据分类为基本数据类型和引用数据类型,然后制定了怎么处理这些数据的方式、方法,每种数据类型都有自身特有的方法、特性,处理方式也不同。
javascript分为三个部分:ECMAScript(核心)、DOM(文档对象模型)、BOM(浏览器对象模型)。
ECMAScript
我们常见的Web浏览器只是ECMAScript实现可能的宿主环境之一,宿主环境不仅提供基本的ECMAScript实现,同时也会提供该语言的扩展,如DOM、BOM,以便语言与环境之间对接交互。其他宿主环境包括Node和Adobe Flash。
注意:ECMAScript不是一个模块也不是一个框架,它只是一个标准,各大浏览器按照它的标准来定义各种接口。
DOM
HTML指的是超文本标记语言,不是一种编程语言,而是一种标记语言,标记语言是一套标记标签,HTML使用标记标签来描述网页,HTML文档包含了HTML标签及文本内容,HTML文档也叫做web页面。
DOM是浏览器提供的ECMAScript语言的扩展,针对XML但经过扩展用于HTML的应用程序编程接口。DOM把XML或HTML映射为一个多层节点构成的结构。XML或HTML页面中的每个组成部分都是某种类型的节点,这些节点都拥有各自的特点、数据和方法,另外也与其他节点存在某种关系。节点之间的关系构成了层次,而所有页面标记则表现为一个以特定节点为根节点的树形结构。
我们看到的WEB页面其实是一个文档(HTML文档),被浏览器解析为页面。DOM将HTML文档解析为一个由节点和对象(包含属性和方法的对象)组成的结构集合(即document)。简而言之,它会将web页面和脚本或程序语言连接起来。所有操作和创建页面的属性、方法和事件都会被组织成对象的形式(例如,document对象表示文档本身)。document是window的一个对象属性,表示文档结构,用于获取页面节点的,window是浏览器打开的窗口(页面),所有的方法属性都在里面,document也在,用于脚本操作页面用的。
如果要改变页面,就需要对html进行增删改查,那么javascript就需要获得对html文档中所有元素进行访问的接口,这些接口都是通过DOM获得的。DOM将html解析成document对象,然后js就可以通过document对象来对html进行操作。
BOM
BOM(Browser Object Model) 是指浏览器对象模型,是用于描述这种对象与对象之间层次关系的模型,浏览器对象模型提供了独立于内容的、可以与浏览器窗口进行互动的对象结构。BOM由多个对象组成,其中代表浏览器窗口的Window对象是BOM的顶层对象,其他对象都是该对象的子对象
总结:
ECMAScript是一种规范,JavaScript是实现这种规范的脚本语言,浏览器是JavaScript宿主环境(载体)。
DOM可以将HTML映射为document对象,这样子HTML就可以被脚本语言操作。
BOM的核心对象是window,它表示浏览器的一个实例对象。
HTML是一种标签语言,用来描述网页。
Css可以被浏览器解析成Css Tree。
项目是用html、js、css写的,会被webpack打包成文件存储在本地,有点像本地服务器,然后通过http://localhost:8080就可以访问,有点像前端用http访问后端服务器的形式,访问之后就可以把打包后的文件加载到浏览器中,可以在谷歌浏览器调试工具中sources面板中看到加载了哪些文件,因为浏览器实现了ECMAScript规范,所以文件中写的js就可以被浏览器解析,知道我写的代码是要实现什么行为的,同时提供了ECMAScript的扩展DOM,DOM将html映射(解析)为一个多层节点的结构document对象,这样子就可以通过ECMAScript来操作document对象来修改html,在控制台打印document就可以看到自己写的html,打印window,就可以看到document对象,类似树形结构,所以被称为DOM树,我们可以看到document是一个对象,每个节点也都是一个对象,里面有这个节点的样式、数据、方法。css会被浏览器的CSS Rule解析成CSS Rule Tree,合并DOM树和CSS规则,生成render树,布局render树(Layout/reflow),负责各元素尺寸、位置的计算,绘制render树(paint),绘制页面像素信息,最后通过GPU渲染在页面上。
Style(计算样式):确定每个 DOM 元素应该应用什么 CSS 规则。
Layout(布局):计算每个 DOM 元素在最终屏幕上显示的大小和位置。由于 web 页面的元素布局是相对的,所以其中任意一个元素的位置发生变化,都会联动的引起其他元素发生变化,这个过程叫 reflow。
Paint(绘制):在多个层上绘制 DOM 元素的的文字、颜色、图像、边框和阴影等。
Composite(渲染层合并):按照合理的顺序合并图层然后显示到屏幕上。
GPU:图形处理器
重新渲染,就需要重新生成布局和重新绘制。前者叫做"重排"(reflow),后者叫做"重绘"(repaint)。
需要注意的是,"重绘"不一定需要"重排",比如改变某个网页元素的颜色,就只会触发"重绘",不会触发"重排",因为布局没有改变。但是,"重排"必然导致"重绘",比如改变一个网页元素的位置,就会同时触发"重排"和"重绘",因为布局改变了。重排和重绘会不断触发,这是不可避免的。但是,它们非常耗费资源,是导致网页性能低下的根本原因。
https://palmer.arkstack.cn/2018/03/DOM%E6%93%8D%E4%BD%9C%E6%88%90%E6%9C%AC%E5%88%B0%E5%BA%95%E9%AB%98%E5%9C%A8%E5%93%AA%E5%84%BF/
https://imweb.io/topic/56841c864c44bcc56092e3fa
https://www.html5rocks.com/zh/tutorials/internals/howbrowserswork/
async和defer
没有async和defer,浏览器会立即加载并执行指定的脚本,使用async属性可以在HTML解析期间下载文件,并在完成下载后暂停HTML解析器来执行它,使用defer属性在HTML解析期间下载该文件,并且只在HTML解析器完成之后执行该文件。延迟脚本也被保证按照它们在文档中出现的顺序执行。
2151798436-59da4801c6772_articlex.png
语句和表达式
表达式返回的是一个结果集。语句有等号也可以是各种条件、循环语句。表达式可以用在html模版中,也可以在箭头函数中用来省略return。注意:javascript语法禁止表达式语句以大括号或关键字"function"开头,需要用()小括号扩起来。
boolean 类型(转换规则Boolean())
虽然boolean类型的字面值只有两个,但ECMAScript中所有类型的值都有与这两个boolean值等价的值。所有数值中“”空字符串、0、NaN、null、undefined这几个会被转为false,其他的全部为true。
浮点数值
注意:0.1+0.2的结果不是0.3,而是0.00000000000000004,如果其他数值相加就不会有错,就是0.1,0.2相加或者0.3减去0.1或0.2就会出错,这个地方要注意。
原因
问题的根源是十进制小数转为二进制小数的过程中,会损失精度。
解决方案
使用toFixed()四舍五入方法。
面向对象的程序设计
对象的属性类型分为数据属性和访问器属性,都是由Object.defineProperty()这个方法定义。
数据属性
- Configurable: 是否可通过delete删除属性从而重新定义属性,默认为true。
- Enumerable: 是否可枚举,默认为true。
- Writable: 是否可修改属性的值,默认为true。
- Value: 属性的值,默认为undefined。
注意:如果直接用Object.defineProperty()去定义属性Configurable、Enumerable、Writable默认值为false。
访问器属性 - Configurable: 是否可通过delete删除属性从而重新定义属性,默认为true。
- Enumerable: 是否可枚举,默认为true。
- Get:在读取属性时调用的函数,默认为undefined。
- Set:在写入属性时调用的函数,默认为undefined。
定义多个属性
Object.defineProperties()接受两个参数,一个是要添加或修改的对象,第二个对象的属性与第一个对象中要添加或修改的属性一一对应。
读取属性的特性
Object.getOwnPropertyDescriptor()接受两个参数,第一个是属性所在的对象,另一个是要读取其描述符的属性名称。
原型链
定义:当以读取模式访问一个实例属性时,首先会在实例中搜索该属性。如果没有找到该属性,则会继续搜索实例的原型,如此层层递进,就构成了实例与原型的链条,这就是所谓原型链的基本概念。
ECMAScript将原型链作为实现继承的主要方法。实现继承基本思路是通过一个类型的实例赋值给另一个构造函数的原型实现的。
网友评论