红宝书(第 4 版)读书系列 --- 第2章
前言:每天碎片时间读一读红宝书,画一画脑图
公众号:前端班车
作者:Yes.man
章节索引
基本知识
- 第 1 章 什么是 JavaScript
- 第 2 章 HTML 中的 JavaScript
- 第 3 章 语言基础
- 第 4 章 变量、作用域与内存
- 第 5 章 基本引用类型
- 第 6 章 集合引用类型
进阶内容
- 第 7 章 迭代器与生成器
- 第 8 章 对象、类与面向对象编程
- 第 9 章 代理与反射
- 第 10 章 函数
- 第 11 章 期约与异步函数
BOM和DOM
- 第 12 章 BOM
- 第 13 章 客户端检测
- 第 14 章 DOM
- 第 15 章 DOM 扩展
- 第 16 章 DOM2 和 DOM3
- 第 17 章 事件
- 第 18 章 动画与 Canvas 图形
- 第 19 章 表单脚本
JavaScript API
- 第 20 章 JavaScript API
- 第 21 章 错误处理与调试
- 第 22 章 处理 XML
- 第 23 章 JSON
- 第 24 章 网络请求与远程资源
- 第 25 章 客户端存储
- 第 26 章 模块
- 第 27 章 工作者线程
JavaScript设计模式和实践策略
- 第 28 章 最佳实践
第2章 HTML中的JavaScript
<script>元素
8个属性
| 属 性 | 描 述 |
|---|---|
| async |
可选,表示应该立即开始下载脚本,但不能阻止其他页面动作,比如下载资源或等待其他脚本加载。只对外部文件有效。 |
| charset | 可选,使用src属性指定的代码字符集。这个属性很少用,因为大多数浏览器不在乎它的值。 |
| crossorigin | 可选,配置相关请求的CORS(跨域资源共享)设置。默认不使用CORS。 crossorigin = "anonymous",配置文件请求不必设置凭据标志。 crossorigin = "use-credentials",设置凭据标志,意味着出站请求会包含凭据。 |
| defer | 可选,表示在文档解析和显示完成后再执行脚本是没有问题的。 只对外部脚本有效。在IE7及更早的版本中,对行内脚本也可以指定这个属性。 |
| integrity | 可选,允许比对接收到的资源和指定的加密签名以验证子资源完整性(SRI,Subresource Integrity)。如果接收到的资源的签名与这个属性指定的签名不匹配,则页面报错,脚本不会执行。这个属性可以用于确保内容分发网络(CDN,Content Delivery Network)不会提供恶意内容。 |
| language | 废弃,最初用于表示代码块中的脚本语言(如“JavaScript”、“JavaScript 1.2” 或 “VBScript”)。大多数浏览器会忽略这个属性,不应该在使用它。 |
| src | 可选,表示包含要执行的代码的外部文件,值是一个URL。 |
| type | 可选,代替language,表示代码块中脚本语言的内容类型(也称MIME类型)。 按照惯例,这个值始终都是“text/javascript”,尽管“text/javascript”和“text/ecmascript”都是已经废弃了。JavaScript文件的MIME类型通常是“application/x-javascript”,不过给type属性这个值有可能导致脚本被忽略。在非IE的浏览器中有效的其他值还有“application/javascript”和“application/ecmascript”。如果这个是“module”,则代码会被当成ES6模块,而且只有这时候代码中才能出现import和export关键字。 |
使用方式
直接在网页中嵌入JavaScript代码
- 直接把代码放在
<script></script>中间 - 包含在
<script>内的代码会被从上到下解释 - 在
<script>中元素中的代码被计算完成之前,页面的其余内容不会被加载,也不会显示 - 在使用
JavaScript行内代码时,要注意代码中不能出现字符串</script>,会导致浏览器报错 - 浏览器解析行内脚本的方式决定了它在看到字符串
</script>时,会将其当成结束的</script>标签,要想避免这个问题,只需要转义字符“ \ ”即可,如console.log("<\/script>");
- 直接把代码放在
通过在它网页中包含外部JavaScript文件
- 使用
src属性实现,会向src属性指定的路径发送一个GET请求,以取得相应资源 - 初始的请求不受浏览器同源策略限制
- 返回并执行的
JavaScript则受限制 - 这个请求仍然受父页面
HTTP / HTTPS协议的限制 - 来自外部域的代码会被当成加载它的页面的一部分来加载和解释,这个能力可以让我们通过不同的域分发
JavaScript - 引用了放在别人的服务器上的
JavaScript文件时要格外小心,因为恶意的程序员随时可能替换这个文件,所以在包含外部域的JavaScript文件时,要确保该域是自己所有的,或者是一个可信的域,integrity属性是防范这种问题的一个武器,但是这个属性也不是所有浏览器都支持 - 浏览器都会按照
<script>在页面中出现的顺序依次解释它们,前提是它们没有使用defer和async属性
- 注意:外部
JavaScript文件扩展名是.js,这不是必须的。 - 因为浏览器不会检查所包含
JavaScript文件的扩展名。 - 这就为使用服务器端脚本语言动态生成
JavaScript代码,或者在浏览器中将JavaScript扩展语言(如TypeScript,或React的JSX)转译为JavaScript提供了可能性。 - 不过要注意,服务器经常会根据文件扩展名来确定响应的正确
MIME类型。如果不打算使用.js扩展名,一定要确保服务器能返回正确的MIME类型。
- 使用
脚本
推迟执行脚本
- 使用
defer属性 - 对于
XHTML文档,指定defer属性时,应该写成defer = "defer"
- 使用
异步加载脚本
- 使用
async属性 - 对于
XHTML文档,指定async属性时,应该写成async = "async"
- 使用
动态加载脚本
- 使用
DOM API,通过向DOM中动态添加script元素同样可以加载指定脚本
let script = document.createElement('script') script.src = 'gibberish.js' document.head.appendChild(script)- 在把
HTMLElement元素添加到DOM且执行到这段代码之前都不会发送请求 - 默认情况下,以这种方式创建的
<script>元素是以异步方式加载的,相当于添加了async属性 - 不是所有浏览器都支持
async属性,如果要统一动态脚本的加载行为,可以明确将其设置为同步加载,script.src = false - 以这种方式获取的资源对浏览器预加载器是不可见的,这会严重影响它们在资源获取队列中的优先级,可能会严重影响性能。要想预加载器知道这些动态请求文件的存在,可以在文档头部显式声明它们:
<link rel="preload" href="gibberish.js">
- 使用
行内代码和外部文件
外部文件是最佳实践
- 可维护性,将代码按功能分散,独立编辑,更易于维护
- 缓存,浏览器会根据特定的设置缓存所有外部链接的
JavaScript文件,这意味着如果两个页面都用到同一个文件,则该文件只需要下载一次,页面加载就会更快 - 适应未来,放到外部文件中,就不必考虑
XHTML或注释黑科技,包含外部JavaScript文件的语法在HTML和XHTML中是一样的
<noscript>元素
- 用于给不支持或者禁用
JavaScript的浏览器提供替代内容 - 可以包含任何可以出现在
<body>中的HTML元素,<script>除外
本文使用 mdnice 排版