红宝书(第 4 版)读书系列 --- 第2章

260 阅读6分钟

红宝书(第 4 版)读书系列 --- 第2章

前言:每天碎片时间读一读红宝书,画一画脑图
公众号:前端班车
作者:Yes.man

章节索引

  • 基本知识
  • 进阶内容
    • 第 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,或ReactJSX)转译为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文件的语法在HTMLXHTML中是一样的

<noscript>元素

  • 用于给不支持或者禁用JavaScript的浏览器提供替代内容
  • 可以包含任何可以出现在<body>中的HTML元素,<script>除外

本文使用 mdnice 排版