重学JavaScript(1)

73 阅读5分钟

这是我参与「掘金日新计划 · 8 月更文挑战」的第10天

前言

从2020年转行成功到现在,将近三年的时间,虽然现有的技术层次能满足日常的业务开发,但仔细回想起来,发现也遗忘了很多,从本篇开始,重新学习JS的内容,并做好笔记。

JavaScript组成

  • 核心:ECMAScript
  • 文档对象模型:DOM
  • 浏览器对象模型(BOM)

ECMAScript

ECMA-262定义的语言(ESx),前端开发将这门语言输出展现在web浏览器环境,但同时,这门语言也能运行在Node环境中(服务器端JavaScript平台)。ECMA-262,演变到现在,也就是我们常说的ES6,ES7等

包含的内容

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

DOM

文档对象模型(DOM,Documen Object Model)是一个应用变成接口(API),用于在HTML中使用廓镇的XML

BOM

浏览器对象模型,用于访问和操作浏览器行为,例如navigator对象,访问该对象可以获取关于浏览器的详尽信息等

script标签

在html文件中,插入js通常是包括在标签中,或者通过标签的src属性来引入一个外部的js文件。script标签有如下属性:

  • async:可选。表示应该立即开始下载脚本,但不能组织其他页面动作,比如下载资源或等待其他脚本加载。只对外部脚本文件有效。
  • charset:可选。使用src指定的代码字符集。大多数浏览器不在乎这个参数的值,所以实际上使用很少。
  • crossorigin:可选。配置相关请求的CORS(跨源资源共享,即跨域)设置。默认不使用。crossorigin="anonymous"配置文件请求不必设置凭据标志;crossorigin="use-credentials"设置凭据标志,意味着出站请求会包含凭据
  • defer:可选。表示脚本可以延迟到文档完全被解析和显示之后再执行,只对外部脚本文件有效。
  • integrity:可选。允许比对接收到的资源和指定的加密签名以验证子资源完整性。如果接收的资源签名和该属性指定的不匹配,则不会执行脚本,且页面报错。用于确保内容分发网络(CDN)不会提供恶意内容
  • language:已废弃
  • src:可选。指定外部js文件路径或链接
  • type:可选。代替language,标识代码块脚本语言的类型,值是“text/javscript”。如果值是module,则代码会被当成ES6模块,只有这时候代码中才能出现import和export关键字

包含在script标签中的代码从上到下依次执行,并且只有在script标签中的代码被计算完成之后,页面的其他内容才会被加载,页面才会显示。

script标签中的js代码中不能出现,这会导致浏览器报错,浏览器会将其当做是script标签的结束。

script标签引用外部js文件,一定要使用src属性。并且,在解析外部js文件时,页面也会阻塞,阻塞时间还包含下载文件的时间。并且,使用了src属性后,不应该在标签内在书写代码,script标签会忽略标签内包含的代码。当src的值是一个完整的url时,这个url指向的资源可以跟包含它的HTML页面不在同一个域中,即不受浏览器同源策略限制,但返回并被执行的js则受限制。src的请求依旧受父页面HTTP/HTTPS协议的限制。在使用src属性引用外部js文件时,由于请求不受同源策略限制,要保证外部的js资源可信。

标签书写位置

最初,script标签放在head标签中,目的主要是把外部的CSS和JS文件集中到一起,但这就意味着要等所有的js文件都下载、解析、解释完成之后,才会开始渲染页面(浏览器解析到body标签起始时开始徐渲染)。如果有多个script,页面渲染就会延迟,导致较长的白屏时间。为了解决这个问题,现在通常将其放在body标签的后面:

<!DOCTYPE html>
<html>
    <head>
        <title>test
    </head>
    <body>
        <!-- 页面内容 --》
        <script src="example1.js"></script>
        <script src="example2.js"></script>
    </body>
</html>

这样页面会在script标签之前渲染页面,白屏时间减少。

另外,script的defer属性也能实现同样的效果,但是只对外部的js文件有效。defer属性表示脚本在执行的时候不会改变页面的结果,即脚本会被延迟到整个页面都解析完毕后在运行。建议只使用一个,因为不能保证第一个推迟的脚本一定会在第二个推迟脚本之前执行。

动态加载脚本

使用DOM的API,动态创建script标签,并赋值src属性,可以实现动态添加script标签并引入外部js文件。

let script = document.createElement('script');   
script.src = 'gibberish.js';    
script.async = false; // 动态的方式是异步方式加载的,相当于async,但并不是所有浏览器都支持async属性
document.head.appendChild(script);

这种方法会影响资源获取的优先级,所以实际开发中并不常见。

script标签总结

日常开发中,建议使用script标签链接外部js文件,理由如下:

  • 可维护性。统一文件管理js代码,比和html写在同一个页面看上去更简洁,更方便维护。
  • 缓存。浏览器会根据特定的设置缓存所有的外部链接的js文件,这意味着如果多次使用同一个文件,只需要下载一次,页面加载更快

noscript标签

用于不支持scrpt或者禁用script的浏览器提供替代内容。该标签可以包含任何出现在body标签中的html元素,除了script标签元素

    <! DOCTYPE html>  
        <html>
            <head> 
                <title>Example HTML Page</title>
                <script defer="defer" src="example1.js"></script>   
                <script defer="defer" src="example2.js"></script>
            </head>
            <body> 
                <noscript>
                    <p>This page requires a JavaScript-enabled browser.</p>
                </noscript>  
            </body>   
        </html>

上述例子用于在脚本不可用时,浏览器显示一段话。如果脚本可被执行,则用户永远看不到这句话。

学习资料

JavaScript高级程序设计(第4版)