你不懂JS:入门篇:第一章(什么是JavaScript?)笔记
第一章:什么是 JavaScript?
第一章:什么是 JavaScript?
- JavaScript 不是 Java 的脚本部分。
- TC39 指定的语言,并由 ECMA 标准机构正式确定的语言的正式名称是ECMAScript。
- TC39是管理 JS 的技术指导委员会,由来自 Mozilla、Google、Apple 和 Samsung 等不同公司的约 50-100 人组成。
- ECMA——标准组织。
- 所有 tc39 提案都可以在这里找到:https://github.com/tc39/proposals
- v8 引擎- Chrome 的 JS 引擎
- SpiderMonkey引擎——Mozilla的JS引擎
Web 统治着关于 (JS) 的一切
- 运行JS的环境种类正在不断增加。
- 但是,主宰 JavaScript 的环境是 Web。
并非所有(Web)JS...
- 各种 JS 环境(如浏览器 JS 引擎、Node.js 等)会将 API 添加到 JS 程序的全局范围内,从而赋予程序特定于环境的功能,例如在用户的浏览器中弹出警报框。
- 这些内容在实际的JS规范中并未提及。
- 此类 API 的一些示例有:fetch(..)、getCurrentLocation(..)、getUserMedia(..) 和 fs.write(..)。
- 即使是console.log() 和所有其他 console 方法都没有在 JS 规范中指定,但几乎在每个 JS 环境中都会使用。
- 人们抱怨的JS跨浏览器差异大多是“太不一致了!”之类的说法,实际上都是由于浏览器环境行为的差异造成的,而不是JS本身的差异。
并非总是 JavaScript
- console/REPL(读取-求值-打印循环)不是 JS 环境,它们是开发者工具。
- 它们的主要目的是让开发者的工作更轻松。
- 我们不应该期望这类工具总是严格遵守 JS 程序的处理方式,因为这不是这些工具的目的。
多面人
- 典型的范式级代码类别包括:
- 程序化——遵循自上而下的线性方法,通过预先确定的一系列操作来实现。
- 面向对象——将逻辑和数据收集到称为类的单元中。
- 函数式编程——将代码组织成函数。
范式是指导程序员解决问题的方向。
- C 是过程式语言,Java 和 C++ 是面向对象的语言,而 Haskell 是函数式语言。
- 有些语言支持混合使用多种范式编写的代码,这些语言被称为“多范式语言”。
- JavaScript 绝对是一种多范式语言。
向后和向前
- JavaScript 实践了向后兼容性。
- 向后兼容性:这意味着一旦某个代码被接受为有效的 JS 代码,语言的任何未来变化都不会导致该代码变成无效的 JS 代码。
- TC39成员经常宣称:“我们不会破坏网络! ”
- 向前兼容性:向前兼容性意味着,在程序中包含语言的新添加项不会导致该程序在较旧的 JS 引擎中运行时崩溃。
- JS 不向前兼容。
- 例如, HTML 和 CSS向前兼容,如果你把 2020 年的代码提取出来,尝试在旧版浏览器中运行,浏览器会跳过无法识别的 HTML/CSS 部分,但不会导致页面崩溃(尽管页面显示效果可能有所不同)。但它们不向后兼容。
跨越差距
- 由于 JS 不向前兼容,因此总会有一些有效的 JS代码,但在较旧的浏览器或环境中无法运行。
- 因此,JS开发者需要特别注意解决这一问题。对于新的、不兼容的语法,解决方案是进行转译。
- 转译:将较新的 JS 语法版本转换为旧浏览器和环境支持的等效旧语法。
- 最常用的转译器是Babel。
- 强烈建议开发者使用最新版本的 JS,这样才能编写出简洁的代码,并更有效地表达其理念。
填补空白
- 如果向前兼容性问题不是由于新的语法,而是由于最近添加的 API 方法,则解决方案是定义最近添加的 API,使其表现得就像旧环境中已经原生定义了它一样。
- 这种模式被称为填充图案。
- 例子:
// getSomeRecords() returns us a promise for some
// data it will fetch
var pr = getSomeRecords();
// show the UI spinner while we get the data
startSpinner();
pr.then(renderRecords).catch(showError).finally(hideSpinner);
// render if successful
// show an error if not
// always hide the spinner
这段代码使用了 ES2019 的特性,因此在 ES2019 之前的环境中无法工作,因为finally(..)方法不存在,并且会发生错误。
为了实现这一点,我们可以将 finally(..) 方法定义为:
if (!Promise.prototype.finally) {
Promise.prototype.finally = function f(fn) {
return this.then(
function t(v) {
return Promise.resolve(fn()).then(function t() {
return v;
});
},
function c(e) {
return Promise.resolve(fn()).then(function t() {
throw e;
});
}
);
};
}
警告:这只是一个简单的示例,展示了 finally(..) 的基本(并非完全符合规范)polyfill。请勿在代码中使用此 polyfill;请尽可能使用更完善、更官方的 polyfill,例如 ES-Shim 中的 polyfill/shim 集合。
诠释中包含什么?
- 用JS编写的代码:它是解释执行的脚本还是编译执行的程序?
- 真正重要的是要清楚地了解 JS 是解释执行还是编译执行,这与 JS 中错误处理的性质有关。
- 从历史上看,解释型或脚本型语言通常是自上而下、逐行执行的。
- 有些语言在执行之前会经过一个处理步骤(通常是解析)。解析过程会生成整个程序的抽象语法树(AST)。
- 在JS中,源代码在执行之前会被解析。
- 所以JS是一种解析型语言,但它是编译型语言吗?答案非常接近“是”而不是“否”。
- 解析后的 JS 代码被转换为二进制形式,然后该二进制形式被执行。
- 因此,JS 是一种编译型语言。正因如此,我们甚至在代码执行之前就能知道其中的错误。
Web Assembly (WASM)
- 2013年,ASM.js 被引入,作为解决 JS 运行时性能压力的一种方法。
- ASM.js 旨在为非 JS 程序(C 等)提供一条转换为可在 JS 引擎中运行的形式的途径。
- 几年后,另一批工程师发布了WebAssembly。
- WASM 是一种更类似于汇编语言的表示格式,JS 引擎可以通过跳过 JS 引擎通常执行的解析/编译步骤来处理它。
- WASM 目标程序的解析/编译是在预先进行的(AOT);分发的是一个二进制打包的程序,JS 引擎只需极少的处理即可执行。
严格来说
- 随着 ES5(2009 年)的发布,JS 添加了“严格模式”作为一种可选机制,以鼓励编写更好的 JS 程序。
- 它应该被视为一种指南,指导我们如何以最佳方式做事,以便 JS 引擎有最大的机会优化和高效地运行代码。
严格模式是通过一个特殊的编译指示(pragma)为每个文件启用的(除了注释/空格之外,它前面不允许有任何其他内容):
// only whitespace and comments are allowed
// before the use-strict pragma
"use strict";
// the rest of the file runs in strict mode
- 也可以在每个功能范围内启用严格模式。
- 有趣的是,如果文件启用了严格模式,则函数级别的严格模式编译指示将被禁用。因此,您必须二选一。
本章到此结束。下一章的笔记我稍后奉上。
祝您编程愉快!
如果您喜欢这些笔记,或者有任何建议或疑问,请在评论区留言。
如果您想与我联系,请点击以下链接:

