「读书笔记」JavaScript高级程序设计第1-2章

320 阅读6分钟

第1章 什么是JavaScript

历史回顾

一开始JS主要是用于代替服务端语言处理输入验证的。

在网络刚起步的阶段,表单验证需要经过服务器往返通信,在那个年代,网速慢,服务器性能差,为了提高用户体验,不得不采取本地端(浏览器)验证,而JS就是这时期为了解决这个问题而诞生的脚本语言。

JavaScript的实现

JS主要分三大内容:

  • ECMAScript 核心语法规范
  • DOM 文档对象模型
  • BOM 浏览器对象模型

ECMAScript

ECMAScript是国际化标准的JS语言,Web浏览器只是ECMAScript可能实现的一种宿主环境。宿主环境提供ECMAScript的基准实现和环境自身交互需要的扩展。这里的扩展比如说DOM的API,这些扩展主要使用ECMAScript的核心类型和语法,并且能够提供额外的功能,像宿主环境还有服务端JavaScript平台Nodejs。

ECMAScript描述以下内容:

  • 语法
  • 类型
  • 语句
  • 关键字
  • 保留字
  • 操作符
  • 全局对象

DOM

DOM全面(Document Object Model)翻译过来叫文档对象模型,是一个应用编程接口(浏览器提供的API),DOM把整个页面抽象成一组分层节点

<html>
   <head>
     <title>我是标题</title>
   </head>
   <body>
     <p>我是内容</p>
   </body>
</html>

上面的解构用DOM可以表示为以下形式 DOM通过创建表示文档的树,让开发者可以随心所欲地控制页面内容和解构,使用DOM提供的API,可以轻松完成增删改查功能。

由于一开始各大浏览器都推出自家浏览器,DOM也是不同的,如果这样的情况持续下去很有可能程序员要面向浏览器编程,于是DOM标准就制定出来了。

DOM并非只能用JS访问,而且确实被其他很多语言实现了,只是对于浏览器来说,DOM就是使用ECMAJavascript实现的,如今DOM已经成为JS的一大组成部分。

DOM主要模块如下:

  • 映射文档解构
  • DOM视图 描述追踪文档不同视图的接口(比如说应用css样式前后的文档)
  • DOM事件 描述事件和事件处理的接口
  • DOM样式 描述处理元素CSS样式的接口
  • DOM遍历和范围 描述遍历和操作DOM树的接口
  • 其他

BOM BOM是浏览器对象模型,用于访问和操作浏览器的窗口。除了页面意外的部分都可以算是BOM的领域。

BOM跟DOM不一样,它没有标准,但随着HTML5页面的到来,这个版本以正式形式涵盖了尽可能多的BOM特性。

BOM主要是针对浏览器窗口和子窗口,以及特定浏览器的扩展。

BOM的扩展如下:

  • 弹出新浏览器的能力
  • 移动、缩放和关闭浏览器窗口的能力
  • navigator对象,提供关于浏览器详尽的内容
  • location对象,提供浏览器加载页面的详尽信息
  • screen对象,提供关于用户屏幕分辨率的详尽信息
  • performance对象,提供浏览器内存占用、导航行为和时间统计的详尽信息
  • 对cookie的支持
  • 其他对象,比如XMLHttpRequest。

小结

JavaScript这门语言主要用来与网页交互,包含以下三部分

  • ECMAScript,是国际化标准定义的JS并提供核心功能
  • 文档对象模型DOM,提供与网页内容交互的方法和接口
  • 浏览器对象模型BOM,提供与浏览器交互的方法和接口

第二章

script元素

把JS插入到HTML中主要是通过<script>这个标签,它比较重要的属性如下:

  • async 表示异步加载脚本,不推荐用,因为次序无法控制
  • defer 表示JS要等文档完全解析后再开始执行
  • src 包含要执行的外部文件地址,只有加了这个属性才能引入外部JS文件。加了这个属性就不能再把代码放在<script>标签内部,会被忽略
  • type 表示语言类型 一般来说浏览器都会顺着script在页面中出现的顺序来依次解释它们,前提是它们没有用defer和async属性。

标签位置

一般来说script要放到body元素中内容的最后面

<body>
这里是内容
  <script src='xxxx.js'></script>
</body>

这样的话页面会先渲染完成再加载JS,用户就会觉得页面刷新比较快

推迟执行脚本

如果说我就不想放到body上,想要放到head上可以吗?可以的,加defer属性

defer属性的意思是推迟执行js代码,加了这个属性后,我们的script标签可以放在head上,理论来说,加了这个属性也会让不同的js文件按照标签顺序加载,但是实际上不一定。所以如果想用的话要保证只有一个外部引入的JS文件

而且这货兼容性不是很好,属于后出的属性,所以还是乖乖放body上吧

动态加载脚本

通过DOM的API可以向DOM动态添加script元素也可以加载指定脚本。

let script=document.createElement('script')
script.src='xxxxx.js'
script.async=false
document.head.appendChild(script)

由于这种方式是异步执行的,就好像加了async属性,除了兼容性问题还可能无法控制加载次序,所以最好要把async属性给改成false。这样就是同步加载,按照次序执行。

行内文件和外部文件

最佳实践是不要把JS代码放到script中,而是单独建一个JS文件外部引入。

理由:

1、可维护性。用一个目录保存JS文件更容易维护

2、缓存。浏览器默认会缓存所有外部引入的文件,如果两个页面同时用到这一个文件,加载会更快

3、适应未来。

noscript元素

这个标签是古老的标签,有些早期浏览器不支持JavaScript,于是就诞生了这个标签来优雅降级,在下面两种情况下,浏览器会渲染在noscript标签内的内容

  • 浏览器不支持脚本(现在几乎不可能)
  • 浏览器支持脚本但是功能被关闭
<noscript>不支持js时会看到这句话</noscript>

小结

JavaScript通过script标签插入html页面中,可以行内写也可以外部引入

  • 外部引用就加src属性
  • script元素在不加asyncdefer的情况下会按照顺序被浏览器解析
  • 浏览器会按照顺序执行解析,为了保证用户的体验,最好是把script标签放到内容最后面</body>前面
  • defer属性可以让script放到head上也不影响渲染页面,但是它的次序并不能保证,虽然理论上是按照次序的。 *async属性可以让script异步加载,不影响渲染,但是次序无法保证
  • noscript标签可以用来指定不支持或者关闭JS脚本支持时页面显示的内容,如果浏览器支持那就不渲染里面的内容

总结

通过第1章,我们大概了解JS的结构:核心功能、DOM、BOM。

通过第2章,我们知道了JS插入html页面中的方式是使用script标签,多个script标签时默认是按照顺序解析的,然后对script元素的属性做了一些了解,其中比较重要的是src属性,async属性和defer属性,当然如何引入都取决于人,采用动态加载的方式引入也是可以的。

在使用这些方法时,最好能够清楚它所带来的缺点,比如async的优点是解析JS不会造成渲染页面阻塞,但是会导致解析js的次序无法控制。defer属性,可以让我们把script标签放到head上,等到页面渲染完成才开始解析JS,但是次序依然不可控。要小心这些属性的缺点,目前来说最好的实践的实践还是把script标签放到内容最下面。