《JavaScript高级程序设计》读书笔记P0-P20

390 阅读8分钟

写此读书笔记是为了让没有读过此书的小伙伴们能够快速阅读,也方便我后面复习,我也能够在每天的学习过程中小小的休息,有不准确或不全面的地方欢迎指出。

前二十页重点不多,粗略看看即可,以下是我认为的重点。

前20页包含两章

  • 什么是JavaScript?
  • HTML中的JavaScript

第一章 什么是JavaScript

1.1 JS的历史(不重要,略过)

1.2 JS实现

1.2.1 ECMAScript

这一节讲述了ES的历史。

ECMAScript不同版本以“edition”表示(也就是描述特定实现的ECMA-262的版本)。初学者应知道ECMA-262是什么。

  • ECMA-262第一版本质上跟网景的JavaScript 1.1相同。
  • 第二版只是做了一些编校工作,主要为了严格符合ISO/IEC-16262(不需要知道是什么)的要求,并没有增减或改变任何特性。
  • 第三版更新了字符串处理、错误定义和数值输出。此外还增加了正则表达式、新的控制语句、try/catch异常处理的支持,以及为了更好地让标准国际化所做的少量修改。
  • 第四版包括强类型变量、新语句和数据结构、真正的类和经典的继承以及操作数据的手段。同时由于第四版跳跃太大,ES3.1发布。
  • ECMA-262的第五版则是ES3.1,主要厘清了第三版存在的歧义,也增加了新功能。新功能包括原生的解析和序列化JSON数据的JSON对象、方便继承和高级属性定义的方法,以及新的增强ES引擎解释和执行代码能力的严格模式。
  • 第六版则是我们熟悉的ES6(也称ES2015或ES Harmony),这一版包含了大概这个规范有史以来最重要的一批增强特性。正式支持了类、模块、迭代器、生成器、箭头函数、期约、反射、代理、和众多新的数据类型。
  • 第七版俗称ES7或ES2016,这次修订只包含少量语法层面的增强,如Array.prototype.includes和指数操作符。
  • 第八版也称ES8、ES2017,主要增加了异步函数(async/await)、SharedArrayBuffer及Atomics API,以及Object.values()/Object.entries()/Object.getOwnPropertyDescription()和字符串填充方法,另外明确支持对象字面量最后的逗号。
  • 第九版也称ES9、ES2018,包括异步迭代、剩余和扩展属性、一组新的正则表达式特性、Promise finally(),以及模板字面量修订。 第十版也称ES10、ES2019增加了Array.prototype.flat()/flatMAP()\String/prototype.trimaStart()/trimEnd()、Object.fromEntries()方法,以及 Symbol.prototype.description 属性,明确定义了 Function.prototype.toString()的返回值并固定了 Array.prototype.sort()的顺序。另外,这次修订解决了与 JSON 字符串兼容的问题,并定义了 catch 子句的可选绑定。
1.2.2 DOM(提供与网页内容交互的方法和接口)

文档对象模型(DOM Document Object Model)是一个应用编程接口(API),用于在 HTML 中使用扩展的 XML。DOM 将整个页面抽象为一组分层节点。

DOM 通过创建表示文档的树,让开发者可以随心所欲地控制网页的内容和结构。使用 DOM API, 可以轻松地删除、添加、替换、修改节点。

1.2.3 BOM(提供与浏览器交互的方法和接口)

浏览器对象模型(BOM) API,用于支持访问和操作浏览器的窗口。使用 BOM,开发者可以操控浏览器显示页面之外的部分。而 BOM 真正独一无二的地方,当然也是问题最多的地方,就是它是唯一一个没有相关标准的 JavaScript 实现。HTML5 改变了这个局面,这个版本的 HTML 以正式规范的形式涵盖了尽可能多的 BOM 特性。

第二章 HTML中的JS

只写重点

  • <\script>中的代码会被从上到下解释。在<\script>元素中的代码被计算完成之前,页面的其余内容不会被加载也不会被显示。
  • 按照惯例,外部 JavaScript 文件的扩展名是.js。这不是必需的,因为浏览器不会检查所包含 JavaScript 文件的扩展名。这就为使用服务器端脚本语言动态生成 JavaScript 代码,或者在浏览器中将 JavaScript扩展语言(如TypeScript,或React的 JSX)转译为JavaScript提供了可能性。
  • <\script>元素的一个最为强大、同时也备受争议的特性是,它可以包含来自外部域的 JavaScript 文件。跟<\img>元素很像,<\script>元素的 src 属性可以是一个完整的 URL,而且这个 URL 指向的资源可以跟包含它的 HTML 页面不在同一个域中,比如这个例子:

<\script src="www.somewhere.com/afile.js"></script>

浏览器在解析这个资源时,会向 src 属性指定的路径发送一个 GET 请求,以取得相应资源,假定是一个 JavaScript 文件。这个初始的请求不受浏览器同源策略限制,但返回并被执行的 JavaScript 则受限制。当然,这个请求仍然受父页面 HTTP/HTTPS 协议的限制。

  • 标签位置,此处很重要,涉及到优化用户体验(说点废话:用户体验是我最注重的一部分,也是前端的魅力之一,说的优雅点,用户体验是一门艺术,也是前端可以不断优化的要素之一)

过去,所有<\script>元素都被放在页面的<\head>标签内,这种做法的主要目的是把外部的 CSS 和 JavaScript 文件都集中放到一起。不过,把所有 JavaScript文件都放在<\head>里,也就意味着必须把所有 JavaScript 代码都下载、解析和解释完成后,才能开始渲染页面(页面在浏览器解析到<\body>的起始标签时开始渲染)。对于需要很多 JavaScript 的页面,这会导致页面渲染的明显延迟,在此期间浏览器窗口完全空白。为解决这个问题,现代 Web 应用程序通常将所有 JavaScript 引用放在<\body>元素中的页面内容后面。 这样一来,页面会在处理 JavaScript 代码之前完全渲染页面。用户会感觉页面加载更快了,因为浏 览器显示空白页面的时间短了。也就是减少白屏时间以提高用户体验

  • 推迟执行脚本

在<\script>元素上设置 defer 属性,相当于告诉浏览器立即下载,但延迟执行。

  • 异步执行脚本

HTML5 为<\script>元素定义了 async 属性。从改变脚本处理方式上看,async 属性与 defer 类似。当然,它们两者也都只适用于外部脚本,都会告诉浏览器立即开始下载。不过,与 defer 不同的是,标记为 async 的脚本并不保证能按照它们出现的次序执行。

给脚本添加 async 属性的目的是告诉浏览器,不必等脚本下载和执行完后再加载页面,同样也不必等到该异步脚本下载和执行后再加载其他脚本。正因为如此,异步脚本不应该在加载期间修改 DOM。

  • 动态加载脚本

除了<\script>标签,还有其他方式可以加载脚本。因为 JavaScript 可以使用 DOM API,所以通过 向 DOM 中动态添加 script 元素同样可以加载指定的脚本。只要创建一个 script 元素并将其添加到 DOM 即可。

let script = document.createElement('script'); 
script.src = 'gibberish.js'; 
document.head.appendChild(script); 

当然,在把 HTMLElement 元素添加到 DOM 且执行到这段代码之前不会发送请求。默认情况下,以这种方式创建的<\script>元素是以异步方式加载的,相当于添加了 async 属性。不过这样做可能会有问题,因为所有浏览器都支持 createElement()方法,但不是所有浏览器都支持 async 属性。因此,如果要统一动态脚本的加载行为,可以明确将其设置为同步加载:

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

以这种方式获取的资源对浏览器预加载器是不可见的。这会严重影响它们在资源获取队列中的优先级。根据应用程序的工作方式以及怎么使用,这种方式可能会严重影响性能。要想让预加载器知道这些动态请求文件的存在,可以在文档头部显式声明它们:

<link rel="preload" href="gibberish.js">
2.2 行内代码与外部文件

推荐使用外部文件的理由如下。

 可维护性。JavaScript 代码如果分散到很多 HTML 页面,会导致维护困难。而用一个目录保存所有JavaScript 文件,则更容易维护,这样开发者就可以独立于使用它们的 HTML 页面来编辑代码。

 缓存。浏览器会根据特定的设置缓存所有外部链接的 JavaScript 文件,这意味着如果两个页面都用到同一个文件,则该文件只需下载一次。这最终意味着页面加载更快。

 适应未来。通过把 JavaScript 放到外部文件中,就不必考虑用 XHTML 或前面提到的注释黑科技。包含外部 JavaScript 文件的语法在 HTML 和 XHTML 中是一样的。