1 JS简介
2 词法结构
3 类型、值、变量
3.10 变量声明与赋值
[ ] const
赋值后不能修改;
使用const定义标识符,必须进行赋值;
常量的含义是指向的对象不能修改(内存地址不变),但可改变对象的内部属性。
const obj ={ name: 'ywj', age: 18; height: 1.88 } obj.name = 'jwy'; //不报错
在ES6开发中,优先使用const,需要改变时用let。
const x = 1; //声明为全局常量 if (x === 1) { let x =2; //在同一代码块中,x可以引用不同值。 console.log(x); //打印2 } conse.log(x); //回到全局作用域 let x = 3; // 错误!重新声明导致语法错误
[ ] let 和 var 的区别:
var声明的变量不具有块作用域
var声明的全局变量被声明为全局对象的属性;let和const声明的全局变量和常量不是全局变量的属性。
var x = 2;
相当于globalThis.x = 2;
var多次声明同名变量是合法的(少用)。
var多次声明同名变量。for循环不会把
var i
变量的作用域限定在循环体内,每次循环都会重新声明和初始化同一个变量。var变量的声明会被提高到包含函数的顶部。...
4 表达式与操作符
5 语句
6 对象
7 数组
8 函数
8.6 闭包
为实现词法作用域,JS函数对象的内部状态不仅要包括函数代码,还要包括对函数定义所在引用域的引用。函数对象与作用域组合起来解析函数变量的机制。
闭包可以捕获一次函数调用的局部变量,将这些变量作为私有状态。
let uniqueInteger = (function() {
let counter = 0;
return function() {return counter++;};
})());
uniqueInteger() // => 0
uniqueInteger() // => 1
9 类
10 模块
- [ ] 模块化的目标
能够用不同作者和来源的代码模块组装大型程序。主要体现在封装和隐藏私有实现、保证全局命名空间清洁。
[ ] 前期解决方案
利用类、对象、闭包(常用)的弱模块化能力。
实践中,JS的模块化依赖代码打包工具。
10.1 基于类、对象、闭包的模块
JS定义的数学函数和常量并未定义在全局命名空间,而是分组作为属性定义在全局Math对象上。例如,不把SingletionSet
和BitSet
定义为全局类,而是只定义一个全局Sets对象,通过这个对象的属性引用不同类。
使用立即调用的函数表达式实现模块化,只将模块的公共API作为函数的值返回。
eg.
const BitSet = (function() {
// 私有实现细节
function isValid(set, n) {...};
function has(set, byte, bit) {...};
const BITS = new Uint8Array([1,2,3,4,5]);
const MASKS = new Uint8Array([~1,~2,~3,~4,~5]);
// 此模块的公共API就是BitSet类,在此定义并返回
// 此类可用上面定义的私有函数和常量,但这些私有
// 函数和常量对此类的用户是不可见的
return class BitSet extends AbstractWritableSet {
// ...省略实现...
};
}());
10.1.1 基于闭包的自动模块化
10.2 Node中的模块
10.3 ES6中的模块
[ ] 与Node模块化的概念相同点: 每个文件本身都是模块,在文件中定义的常量、变量、函数和类对这个文件而言是私有的,除非被显式导出。
一个模块导出的值只有在显式导入的模块中才可以使用。
[ ] 与Node模块化的概念不同点:
导入和导出所用的语法;
浏览器中定义模块的方式。
[ ] 与常规JS脚本的区别:
在常规脚本中,顶级声明的变量、函数、类会被共享全局上下文。而模块中,每个文件都有自己的私有上下文,可使用import和export语句。
ES6模块中代码自动应用严格模式(不用再写use strict),无法再使用with语句和arguments对象或未声明的变量。严格模式下作为函数调用函数中this是undefined,而模块中this均为undefined(浏览器和Node中的脚本将this设置为全局对象)
10.3.1 ES6的导出
const PI = Math.PI;
function sum(d) {return d * PI}
class Circle {
constructor(r) {this.r = r;}
area() {return PI * this.r * this.r;}
}
export {Circle, sum, PI} // 花括号不代表字面量
在只有一个导出值时,可使用默认导出export default
区别:
**export:**只对有名字的声明有效
**export default:**可导出任意表达式(包括匿名函数和匿名类)
10.3.2 ES6的导入
import BitSet from './bitset.js';
import {mean, stddev} from './stats.js';
import * as stats from './stats.js'; // 全部导入
import './stats.js'; // 导入没有任何导出的模块
不能在类、函数、循环或条件中出现。
标识符字符串必须是一个以'/'
开始的绝对路径,或以'./'
或'../'
开始的相对路径,或是一个带有协议或及主机名的完整URL。
11 JS标准库
12 迭代器与生成器
13 异步JS
13.1 使用回调的异步编程
13.1.1 定时器
13.1.2 事件
13.1.3 网络事件
13.1.4 Node中的回调与事件
13.2 期约
14 元编程
15 浏览器中的JS
15.2 事件
15.2.1 事件类别
15.2.2 注册事件处理程序
方式一:设置事件处理程序属性
方式二:addEventListener(注册处理程序的事件类型, 回调函数, boolean)
16 Node服务器端JS
17 JS工具和扩展
17.5 代码打包
为使用ES6模块,使用代码打包工具从程序的主入口开始,跟着import指令树,找到程序依赖的所有模块。然后把所有独立的模块文件组合成一个JS代码包,并重写import和export指令让代码可以在这种新形势下运行。
[ ] 功能:
为多入口的程序的每个入口创建一个代码包,或生成一个支持多入口的独立包。
函数可以函数式而非静态式使用import()。
打包工具通常会输出源码映射(source map)文件,包含源代码行号和输出包代码行。
找出模块中未使用部分并排除。
...
17.6 使用Babel转译
也称为“转译器”。将ES6+转译为ES5等...
和Webpack一样可生成源码映射(保存转换后的代码与原始代码位置间的映射)
// 在Webpack中,可使用babel-loader
17.6.1 安装
[ ]
@babel/core
:babel的核心代码;[ ]
@babel/cli
:可在命令行使用babel,在Webpack中不需要。npm install @babel/core @babel/cli -D
17.6.2 使用
npx babel demo.js --out-file test.js --presets=@babel/preset-env