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对象上。例如,不把SingletionSetBitSet定义为全局类,而是只定义一个全局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

17.7 JSX