ECMAScript(2)核心语法课件(Node.js/React 环境)
📚 ECMAScript 核心语法课件(Node.js/React 环境)
1. 变量与作用域
变量声明方式
var
:函数作用域,存在变量提升(hoisting)console.log(a); // undefined(变量提升) var a = 10;
let
:块级作用域,无变量提升// console.log(b); // 报错(暂时性死区) let b = 20;
const
:块级作用域,声明时必须初始化,不可重新赋值const c = 30; // c = 40; // 报错
作用域类型
- 全局作用域:在函数外声明,全局可访问
- 函数作用域:
var
声明的变量在函数内有效 - 块级作用域:
let
/const
在{}
内有效(如if
、for
语句)
示例对比
// var 的变量提升
function testVar() {console.log(x); // undefinedvar x = 1;
}// let 的块级作用域
if (true) {let y = 2;
}
// console.log(y); // 报错:y is not defined
2. 数据类型
基本数据类型(7种)
undefined
:未定义的值null
:空值boolean
:true
/false
number
:整数/浮点数(包括NaN
、Infinity
)
let num = 3.14;
let nan = NaN; // 非数字值
string
:字符串(可用单/双引号或模板字符串)
let name = "Alice";
let greeting = `Hello, ${name}!`; // 模板字符串
symbol
:唯一值(ES6+)
let sym = Symbol("id");
bigint
:大整数(ES2020+)
let bigNum = 9007199254740991n;
引用数据类型
object
:对象、数组、函数等let obj = { key: "value" }; let arr = [1, 2, 3]; function func() {}
类型检测方法
typeof
:检测基本类型(注意typeof null === "object"
)instanceof
:检测引用类型(如arr instanceof Array
)Object.prototype.toString.call()
:精确检测所有类型Object.prototype.toString.call([]); // "[object Array]"
3. 运算符与表达式
算术运算符
+
、-
、*
、/
、%
、**
(指数)console.log(2 ** 3); // 8
比较运算符
==
(宽松相等)、===
(严格相等)"5" == 5; // true "5" === 5; // false
逻辑运算符
&&
(与)、||
(或)、!
(非)let value = null || "default"; // "default"
赋值运算符
=
、+=
、-=
、*=
等let count = 10; count += 5; // 15
其他运算符
- 三元运算符:
condition ? expr1 : expr2
let result = score > 60 ? "及格" : "不及格";
- 可选链(
?.
):避免访问null
/undefined
属性(ES2020+)let name = user?.profile?.name; // 安全访问
4. 流程控制
条件语句
if...else
:if (score > 90) {console.log("优秀"); } else if (score > 60) {console.log("及格"); } else {console.log("不及格"); }
switch
:switch (color) {case "red":console.log("红色");break;default:console.log("其他颜色"); }
循环语句
for
:for (let i = 0; i < 5; i++) {console.log(i); }
while
/do...while
:let i = 0; while (i < 5) {console.log(i);i++; }
for...of
(遍历可迭代对象,如数组):let arr = [1, 2, 3]; for (let item of arr) {console.log(item); }
跳转语句
break
:退出循环continue
:跳过本次循环return
:函数返回值
💡 教学建议
- 结合 Node.js 环境演示:使用
node
命令直接运行示例代码,观察结果。 - 对比 TypeScript:在讲解时可提示 TS 的增强点(如类型注解、静态检查)。
- 联系 React 开发:
- 组件状态(
useState
)常用let
/const
声明。 - Props 传递涉及对象类型检测。
- 条件渲染需熟练运用
&&
、三元运算符。
- 组件状态(
- 常见陷阱强调:
var
的变量提升与作用域问题。NaN
的特殊性(NaN !== NaN
)。- 浮点数精度问题(如
0.1 + 0.2 !== 0.3
)。
好的,以下是针对【函数、对象与面向对象、集合、模块化】的 ECMAScript 课件内容和知识点举例,结合了现代 ES6+ 语法和 React 开发中的常见模式。
📘 ECMAScript 核心概念进阶课件
1. 函数
函数定义与提升
- 函数声明:整体提升,可在定义前调用
console.log(add(2, 3)); // 5 (函数提升) function add(a, b) {return a + b; }
- 函数表达式:仅变量提升,不可提前调用
// console.log(multiply(2, 3)); // 报错 const multiply = function(a, b) {return a * b; };
箭头函数 (ES6+)
- 语法简洁,无自身
this
,继承自外层作用域// 传统函数 [1, 2, 3].map(function(x) { return x * x; });// 箭头函数 [1, 2, 3].map(x => x * x); // [1, 4, 9]// React 中的使用:避免 this 绑定问题 const MyComponent = () => <div>Hello World</div>;
默认参数与剩余参数
- 默认参数:为参数提供默认值
function greet(name = "Guest", greeting = "Hello") {return `${greeting}, ${name}!`; } console.log(greet()); // "Hello, Guest!"
- 剩余参数:将不定数量的参数表示为数组
function sum(...numbers) {return numbers.reduce((acc, curr) => acc + curr, 0); } console.log(sum(1, 2, 3, 4)); // 10
2. 对象与面向对象
对象字面量增强 (ES6+)
- 属性简写:变量名直接作为属性名
const name = "Alice"; const age = 25; // ES5 const personOld = { name: name, age: age }; // ES6+ const personNew = { name, age }; // { name: "Alice", age: 25 }
- 方法简写:省略
function
关键字const person = {name: "Bob",// ES5sayHello: function() { console.log("Hello"); },// ES6+sayHi() { console.log("Hi"); } };
- 计算属性名:使用
[]
动态定义属性名const propKey = "firstName"; const person = {[propKey]: "John", // firstName: "John"[`get${propKey}`]() { return this[propKey]; } // getFirstName() };
类 (Class) 语法 (ES6+)
class
定义类,constructor
定义构造函数,extends
实现继承class Person {constructor(name, age) {this.name = name;this.age = age;}// 方法定义在原型上greet() {console.log(`Hello, my name is ${this.name}`);}// 静态方法static describe() {console.log("This is a Person class");} }class Student extends Person {constructor(name, age, grade) {super(name, age); // 调用父类 constructorthis.grade = grade;}study() {console.log(`${this.name} is studying`);} }const alice = new Student("Alice", 22, "A"); alice.greet(); // "Hello, my name is Alice" Student.describe(); // "This is a Person class"
3. 集合
Set
- 成员值唯一,无重复
const numbers = [1, 2, 2, 3, 4, 4, 5]; const uniqueNumbers = new Set(numbers); // Set(5) {1, 2, 3, 4, 5} console.log([...uniqueNumbers]); // [1, 2, 3, 4, 5] (转数组)// 常用方法 const set = new Set(); set.add(1).add(2).add(3); // 添加 console.log(set.has(2)); // true (检查是否存在) set.delete(2); // 删除 console.log(set.size); // 2 (获取大小) set.clear(); // 清空
Map
- 键值对集合,键可以是任意类型
const map = new Map(); const keyObj = { id: 1 };map.set(keyObj, "value associated with object"); // 设置键值对 map.set("name", "Alice");console.log(map.get(keyObj)); // "value associated with object" (获取值) console.log(map.has("name")); // true console.log(map.size); // 2map.delete("name"); // 删除 // map.clear(); // 清空// 遍历 for (let [key, value] of map) {console.log(key, value); }
WeakSet 与 WeakMap
- 弱引用,键必须是对象,不可枚举,无
size
属性,不易造成内存泄漏let obj = { data: "test" }; const weakSet = new WeakSet(); weakSet.add(obj);const weakMap = new WeakMap(); weakMap.set(obj, "some value");// 当 obj = null 时,垃圾回收机制会自动回收 weakSet 和 weakMap 中的记录
4. 模块化 (ES6 Module)
导出 (Export)
- 命名导出:一个模块可导出多个[citation:10][citation:11]
// math.js export const PI = 3.14159; export function square(x) {return x * x; } export class Calculator {add(a, b) { return a + b; } } // 或者最后统一导出 // export { PI, square, Calculator };
- 默认导出:一个模块只能有一个[citation:10][citation:11]
// logger.js const defaultLogger = {log: (msg) => console.log(`LOG: ${msg}`) }; export default defaultLogger;
导入 (Import)
- 导入命名导出:[citation:10][citation:11]
// main.js import { PI, square, Calculator } from './math.js'; console.log(PI);
- 导入默认导出:[citation:10][citation:11]
import logger from './logger.js'; // 名称可自定义 logger.log("Hello");
- 混合导入:[citation:10][citation:11]
import React, { Component } from 'react'; // React 默认导出,Component 是命名导出
- 动态导入:按需加载[citation:10][citation:11]
// 返回一个 Promise import('./module.js').then(module => {module.doSomething();}).catch(err => {console.error("Module loading failed", err);});// 或在 async 函数中使用 async function loadModule() {const module = await import('./module.js');module.doSomething(); }
在 Node.js 和浏览器中使用
- Node.js:在
package.json
中设置"type": "module"
,或使用.mjs
扩展名[citation:10][citation:11]// package.json {"type": "module" }
- 浏览器:使用
<script type="module">
标签[citation:11]<script type="module" src="main.js"></script>
💡 教学提示与最佳实践
-
函数选择:
- 优先使用箭头函数,尤其在需要固定
this
的场景(如 React 事件处理、定时器)。 - 对于需要自身
this
(如对象方法)或需要提升的函数,使用函数声明。
- 优先使用箭头函数,尤其在需要固定
-
面向对象编程:
- 使用
class
语法让代码更清晰易读,更接近传统面向对象语言。 extends
和super
使继承变得简单。
- 使用
-
集合运用:
- 需要存储唯一值时用
Set
。 - 需要键值对且键可能为非字符串时用
Map
(优于普通对象)。 - 处理** DOM 节点**等对象且担心内存泄漏时,考虑
WeakMap
或WeakSet
。
- 需要存储唯一值时用
-
模块化工程:
- ES6 Module 是现代 JavaScript 项目的标准模块化方案。
- 合理使用命名导出和默认导出,保持模块职责单一。
- 动态导入可用于代码分割(Code Splitting),提升大型应用初始加载速度。
-
React 关联示例:
- 函数组件:大量使用箭头函数和默认导出。
// React 函数组件 (通常默认导出) const Welcome = (props) => <h1>Hello, {props.name}</h1>; export default Welcome;
- 类组件:使用
class
和extends Component
。
import React, { Component } from 'react'; class Welcome extends Component {render() {return <h1>Hello, {this.props.name}</h1>;} } export default Welcome;
- Hooks:模块化导入。
import React, { useState, useEffect } from 'react';