历史
- 1995.05:Netscape 公司的 Brendan Eich 用 10 天设计完成了语言的初版(Mocha)
- 1996.12:JavaScript 被提交给 ECMA,并成立 TC39 技术委员会负责制定标准
- 1997.09:正式发布《ECMA-262 第 1 版》(ECMAScript 1.0)
- 1998.07:ECMAScript 2.0 发布
- 1999.12:ECMAScript 3.0 发布
- 2007 - 2008:ES3.1 和 ES4.0 之间争议过大,最终废除了 4.0 版本
- 2009.12:ECMAScript 5.0 发布
- 2011.06:ECMAScript 5.1 发布
- 2015.06:ECMAScript 6.0 发布(更名为 ECMAScript 2015)
- 每年发布一个新版本…
语言特点
- 动态语言(代码内容在运行时决定,类型检查和转换是在程序执行时进行的,而不是在编译时)
- 弱类型语言(可以隐式转换)
- 解释型语言(执行时代码逐句解释)
- 自动分号插入(ECMAScript® 2025 Language Specification (tc39.es))
- 严格区分大小写
变量
- 由
字母
,数字
,_
,$
组成,不能以数字开头 - 硬编码的常量一般使用全大写加下划线的形式:
const DEFAULT_AGE = 18
- 常规命名通常采用驼峰形式:
firstSecond
- 不能以 保留关键字 作为变量名
注释
- 单行:
// xxx
- 多行:
/* xxx */
代码表示 how,注释表示 why
浏览器中 JavaScript 的实现(含义)
- 核心:ECMAScript
- 文档对象模型:DOM
在 HTML 中引入 JavaScript
1. 内联 JavaScript
使用 <script></script>
标签插入 <body>
中,script 的执行会阻塞下面的内容加载和显示:
2. 外部 JavaScript
<script src="script.js"></script>
,如果设置了 src 属性,则 script 标签内部包裹的代码会失效
使用外部引入的好处是浏览器会下载它,然后将它保存到浏览器的缓存中
当浏览器加载 HTML 时遇到 <script>...</script>
标签,浏览器就不能继续构建 DOM,它必须立刻执行此脚本,这会导致两个重要的问题:
- 脚本不能访问到位于它们下面的 DOM 元素,因此,脚本无法给它们添加处理程序等
- 如果页面顶部有一个笨重的脚本,它会阻塞页面。在该脚本下载并执行结束前,用户都不能看到页面内容
在外部 JavaScript 的写法下,可以增加两种属性不阻塞页面:
async
:异步属性,立即在后台下载,但是加载完成后立即执行,与其他脚本不会互相等待,和 DOMContentLoaded 之间也不会互相等待(独立脚本使用)defer
:延迟属性,立即在后台下载,但是在 DOM 解析完成之后,DOMContentLoaded 之前执行,所有 defer 的脚本按照出现顺序执行(需要整个 DOM 或加载顺序重要时使用)
3. 动态脚本
可以使用 JavaScript 动态地创建一个脚本,并将其附加(append)到文档(document)中:
当脚本被 append 到文档时,脚本就会立即开始加载,先加载完成就先执行
默认是异步的,类似 2 中的 async 属性,可以显式设置 script.async=false
变成类似 defer
的效果,但是不会阻塞 DOMContentLoaded 事件
严格模式
ES5 增加了严格模式:"use strict";
必须在文件的开头声明,或者在一个函数的开头声明才有效(class
和 module
中会自动启用严格模式),用于修改旧有 JS 中不完善的地方。严格模式下:
- 变量必须先声明再使用,给未经声明的变量赋值会报错:ReferenceError (非严格模式:会创建一个全局变量)
- 函数声明只在块级作用域中能够访问,非严格模式下则能够全局访问
- 对不可写的属性等进行写入操作时,会出现错误
- 八进制不再允许使用前缀
0
表示,必须使用0o
或0O
eval
有属于自己的词法环境。因此不能从外部访问在 eval 中声明的函数和变量- 增加了保留关键字
- 不能用
with
语句 - this 的值是 undefined,非严格模式下是 window
- 非严格模式下违反对象描述符的行为会被忽略(如:对只读的属性进行赋值),但是严格模式下会报错
转译器 和 Polyfill
JavaScript 语言每年都会增加新的功能,为了在旧引擎中使用新的特性,有 2 种方式:
- 转译器:将源码转译成另一种源码的特殊软件,主要针对从新到旧。如 Babel
- polyfill:更新/添加新函数的脚本,主要针对从无到有。如 core-js(方法在规范中存在,但是引擎还不支持)