JavaScript 核心语法速通

JavaScript 核心语法速通:从基础到 React 开发实战

适合人群:有 Go、Python、Java 等编程经验,希望快速掌握 JavaScript 并进入 React + TypeScript 开发的工程师。

学习目标:掌握 JavaScript 中最重要的变量、数据类型、对象、数组、函数、解构、Promise、async/await 和模块化语法。

一、JavaScript 语法知识体系

JavaScript 与 Go、Python 等语言的核心编程思想类似,但它有一些非常重要的语言特性。

模块 核心知识 优先级
变量声明 const、let、var P0
数据类型 string、number、boolean、null、undefined P0
运算符 ===、!==、?.、??、... P0
条件与循环 if、for、for...of P0
数组 map、filter、find、reduce P0
对象 属性访问、展开运算符、解构 P0
函数 箭头函数、回调函数 P0
异步编程 Promise、async/await P0
模块化 import、export P0
DOM 和事件 querySelector、addEventListener P0
this、原型链、闭包 语言运行机制 P1
class 类与继承 P1

二、变量声明:let、const、var

JavaScript 有三种常见的变量声明方式:

ini 复制代码
var a = 10;
let b = 20;
const c = 30;

1. let:可以重新赋值

ini 复制代码
let count = 0;

count = 1;
count = 2;

console.log(count); // 2

类似 Go 中可以重新赋值的变量。

2. const:不能重新赋值

ini 复制代码
const name = "Kevin";

// 报错
name = "Tom";

注意:const 限制的是变量绑定,不是对象内部数据完全不可修改。

ini 复制代码
const user = {
  name: "Kevin",
  age: 25
};

// 可以修改对象属性
user.age = 26;

// 不允许重新赋值
user = {};

React 项目中通常优先使用 const,只有需要重新赋值时才使用 let。

3. var:旧式变量声明

ini 复制代码
var count = 10;

var 和 let 的重要区别是作用域:

  • var:函数作用域。
  • let:块级作用域。
  • const:块级作用域。

一句话理解:作用域就是变量能在哪些地方被访问。

  • var:函数作用域,只要在同一个函数内部,通常就能访问。
  • let:块级作用域,只能在声明它的 {} 代码块内部访问。

现代开发中,一般不推荐继续使用 var。

结论:默认 const,需要重新赋值时使用 let。


三、JavaScript 数据类型

JavaScript 是动态类型语言,变量不需要提前声明类型。

ini 复制代码
let value = 100;

value = "hello";

value = true;

JavaScript 的原始类型主要有七种:

类型 示例
string "hello"
number 123、3.14
boolean true、false
undefined undefined
null null
bigint 123n
symbol Symbol("id")

此外,对象类型 object 包括普通对象、数组、函数等引用值。

1. string:字符串

ini 复制代码
const name = "Kevin";
const age = 25;

推荐掌握模板字符串:

ini 复制代码
const message = `姓名:${name},年龄:${age}`;

console.log(message);

${} 可以在模板字符串中嵌入表达式。

2. number:数字

JavaScript 普通数字统一使用 number,不区分 int、float 类型。

ini 复制代码
const a = 10;
const b = 3.14;

需要注意:JavaScript Number 是 IEEE 754 双精度浮点数。

例如:

arduino 复制代码
console.log(0.1 + 0.2);
// 0.30000000000000004

另外,超大整数 ID 需要特别注意精度问题。

例如后端返回一个超过 Number.MAX_SAFE_INTEGER 的任务 ID,前端最好使用字符串保存,避免精度丢失。

3. null 和 undefined

这是 JavaScript 的重要区别。

ini 复制代码
let a;

console.log(a); // undefined

const b = null;

通常可以理解为:

  • undefined:没有提供值。
  • null:显式表示空值。

例如:

arduino 复制代码
const user = {
  name: "Kevin"
};

console.log(user.age); // undefined

4. typeof:查看数据类型

javascript 复制代码
console.log(typeof 123);       // number
console.log(typeof "hello");   // string
console.log(typeof true);      // boolean
console.log(typeof undefined); // undefined

特殊情况:

javascript 复制代码
console.log(typeof null); // object

这是 JavaScript 历史遗留行为,不代表 null 真的是普通对象。


四、运算符:重点学习 ===、?.、??、...

1. == 和 ===

JavaScript 有两种相等比较:

ini 复制代码
console.log(1 == "1");  // true
console.log(1 === "1"); // false

区别:

  • ==:允许类型转换后比较。
  • ===:不进行这种隐式类型转换。

实际开发中,推荐优先使用 === 和 !== 。

ini 复制代码
const status = 1;

if (status === 1) {
  console.log("运行中");
}

2. 可选链操作符 ?.

例如:

css 复制代码
const user = {
  profile: {
    name: "Kevin"
  }
};

传统写法:

ini 复制代码
const name = user && user.profile && user.profile.name;

现代写法:

ini 复制代码
const name = user?.profile?.name;

?. 的含义是:

如果左侧为 null 或 undefined,就停止访问并返回 undefined,而不是抛出属性访问错误。

例如:

ini 复制代码
const user = null;

console.log(user?.profile?.name);
// undefined

React 项目中非常常见:

ini 复制代码
const username = response?.data?.user?.name;

3. 空值合并运算符 ??

ini 复制代码
const username = null;

const name = username ?? "默认用户";

console.log(name); // 默认用户

只有左边是 null 或 undefined 时,才使用右边的默认值。

4. ?? 和 || 的区别

arduino 复制代码
const count = 0;

console.log(count || 100); // 100

console.log(count ?? 100); // 0

原因:

  • ||:左边是假值时,返回右边。
  • ??:左边是 null 或 undefined 时,返回右边。

在业务开发中,如果 0 是合法数值,通常更适合使用 ??。

5. 展开运算符 ...

这是 React 开发中非常重要的语法。

数组:

ini 复制代码
const a = [1, 2];
const b = [...a, 3, 4];

console.log(b); // [1, 2, 3, 4]

对象:

ini 复制代码
const user = {
  name: "Kevin",
  age: 25
};

const newUser = {
  ...user,
  age: 26
};

输出:

css 复制代码
{
  name: "Kevin",
  age: 26
}

注意:... 的对象展开是浅拷贝,不会递归复制嵌套对象。


五、条件判断与循环

1. if / else

lua 复制代码
const status = "running";

if (status === "running") {
  console.log("任务运行中");
} else if (status === "failed") {
  console.log("任务失败");
} else {
  console.log("未知状态");
}

2. 三元运算符

ini 复制代码
const age = 20;

const result = age >= 18 ? "成年人" : "未成年人";

等价于简单的 if/else 赋值。

在 React JSX 中尤其常见:

arduino 复制代码
function Status({ running }) {
  return (
    <span>
      {running ? "运行中" : "已停止"}
    </span>
  );
}

3. for 循环

css 复制代码
for (let i = 0; i < 5; i++) {
  console.log(i);
}

4. for...of

用于遍历可迭代对象的值。

ini 复制代码
const tasks = ["任务A", "任务B", "任务C"];

for (const task of tasks) {
  console.log(task);
}

5. for...in

用于遍历对象的可枚举字符串属性键。

vbnet 复制代码
const user = {
  name: "Kevin",
  age: 25
};

for (const key in user) {
  console.log(key, user[key]);
}

注意:for...in 也可能遍历继承的可枚举属性。只遍历普通对象自身键时,通常推荐 Object.keys()、Object.entries()。


六、数组:React 中最重要的数据处理知识

JavaScript 的数组类似 Python 的 list。

bash 复制代码
const tasks = [
  { id: 1, name: "任务A", status: "running" },
  { id: 2, name: "任务B", status: "failed" },
  { id: 3, name: "任务C", status: "running" }
];

需要重点掌握以下方法。

1. map:映射转换

ini 复制代码
const nums = [1, 2, 3];

const result = nums.map(num => num * 2);

console.log(result); // [2, 4, 6]

理解为:

将数组的每个元素经过函数处理,生成一个新数组。

React 中经常使用 map 渲染列表:

javascript 复制代码
function TaskList() {
  const tasks = ["任务A", "任务B", "任务C"];

  return (
    <div>
      {tasks.map(task => (
        <div key={task}>{task}</div>
      ))}
    </div>
  );
}

其中 key 用于帮助 React 识别列表元素,应该在同级列表中保持稳定且唯一。

2. filter:过滤数据

ini 复制代码
const nums = [1, 2, 3, 4, 5];

const result = nums.filter(num => num > 3);

console.log(result); // [4, 5]

业务场景:

ini 复制代码
const runningTasks = tasks.filter(
  task => task.status === "running"
);

这个方法非常适合筛选任务列表。

3. find:查找元素

ini 复制代码
const task = tasks.find(task => task.id === 2);

console.log(task);

find 返回第一个满足条件的元素,找不到返回 undefined。

4. some 和 every

ini 复制代码
const nums = [1, 2, 3];

console.log(nums.some(n => n > 2));  // true
console.log(nums.every(n => n > 0)); // true
  • some:是否存在至少一个满足条件的元素。
  • every:是否所有元素都满足条件。

5. reduce:聚合

ini 复制代码
const nums = [1, 2, 3, 4];

const sum = nums.reduce((total, num) => {
  return total + num;
}, 0);

console.log(sum); // 10

reduce 常用于统计、分组和聚合数据。

例如统计运行中的任务数量:

ini 复制代码
const count = tasks.reduce((total, task) => {
  return total + (task.status === "running" ? 1 : 0);
}, 0);

6. push 和 map 的区别

ini 复制代码
const a = [1, 2];

a.push(3); // 修改原数组

而:

ini 复制代码
const a = [1, 2];

const b = a.map(x => x * 2); // 创建新数组

React 中尤其要注意,不要直接修改 State 数组:

scss 复制代码
// 不推荐
tasks.push(newTask);
setTasks(tasks);

// 推荐
setTasks([...tasks, newTask]);

数组最重要的五个方法:map、filter、find、some、reduce。


七、对象:属性访问与解构赋值

JavaScript 对象类似 Python 字典,或 Go 中用于保存动态字段的 map,但具有自己的属性与原型机制。

arduino 复制代码
const user = {
  name: "Kevin",
  age: 25,
  city: "Beijing"
};

1. 访问对象属性

sql 复制代码
console.log(user.name);

console.log(user["name"]);

两种写法均可。

当属性名需要动态决定时:

ini 复制代码
const key = "age";

console.log(user[key]); // 25

2. 修改对象属性

ini 复制代码
user.age = 26;

3. 解构赋值(非常重要)

传统写法:

ini 复制代码
const name = user.name;
const age = user.age;

解构写法:

arduino 复制代码
const { name, age } = user;

相当于一次性从对象中取出多个属性。

也可以重命名:

arduino 复制代码
const { name: userName } = user;

console.log(userName); // Kevin

4. 数组解构

ini 复制代码
const nums = [10, 20, 30];

const [a, b] = nums;

console.log(a); // 10
console.log(b); // 20

React 的 useState 正是使用数组解构:

scss 复制代码
const [count, setCount] = useState(0);

这里:

  • count:当前状态值。
  • setCount:更新状态的函数。

八、函数:普通函数、箭头函数和回调函数

1. 普通函数

css 复制代码
function add(a, b) {
  return a + b;
}

2. 箭头函数

css 复制代码
const add = (a, b) => {
  return a + b;
};

单表达式可以简写:

css 复制代码
const add = (a, b) => a + b;

3. 函数可以作为参数

scss 复制代码
function execute(callback) {
  callback();
}

execute(() => {
  console.log("执行回调");
});

这种写法在 JavaScript 事件、Promise 和 React 中非常常见。

4. 默认参数

javascript 复制代码
function greet(name = "Guest") {
  console.log(`Hello ${name}`);
}

greet();        // Hello Guest
greet("Kevin"); // Hello Kevin

5. 剩余参数

javascript 复制代码
function sum(...nums) {
  return nums.reduce((a, b) => a + b, 0);
}

console.log(sum(1, 2, 3)); // 6

这里的 ...nums 用于接收不定数量的参数。

它与前面数组或对象的展开语法使用相同的 ... 符号,但作用不同。


九、异步编程:Promise 和 async/await

这是 JavaScript 需要重点学习的部分。

1. 为什么需要异步?

例如浏览器请求后端接口:

scss 复制代码
fetch("/api/tasks");

网络请求需要时间。

JavaScript 不应该因为等待接口返回,就阻塞整个页面的正常交互。

2. Promise

Promise 用来表示一个异步操作最终的完成或失败结果。

ini 复制代码
fetch("/api/tasks")
  .then(response => response.json())
  .then(data => {
    console.log(data);
  })
  .catch(error => {
    console.error(error);
  });

执行流程:

  1. 发起 HTTP 请求。
  2. 等待请求完成。
  3. 请求成功后处理数据。
  4. 发生错误时进入 catch。

注意,fetch 默认只会因为网络等问题拒绝 Promise;HTTP 404、500 等状态需要通过 response.ok 自己判断。

3. async/await(重点)

现代开发中更推荐使用 async/await 组织异步逻辑:

javascript 复制代码
async function getTasks() {
  try {
    const response = await fetch("/api/tasks");

    if (!response.ok) {
      throw new Error(`HTTP ${response.status}`);
    }

    const data = await response.json();

    console.log(data);
  } catch (error) {
    console.error("请求失败", error);
  }
}

理解两个关键词:

  • async:声明异步函数,返回值会被包装成 Promise。
  • await:等待 Promise 结果,在当前 async 函数中暂停后续代码执行。

注意:await 不意味着阻塞整个 JavaScript 主线程等待网络响应。

4. Promise.all:并发执行

例如需要同时请求任务列表和统计数据:

javascript 复制代码
async function loadData() {
  const [tasks, stats] = await Promise.all([
    fetch("/api/tasks").then(r => r.json()),
    fetch("/api/stats").then(r => r.json())
  ]);

  console.log(tasks, stats);
}

Promise.all 会等待所有 Promise 成功完成;只要其中一个拒绝,返回的 Promise 就会拒绝。

后端开发者需要特别注意:Promise 是异步结果的抽象,不等价于 Go 的 goroutine。


十、模块化:import 和 export

现代前端项目通常采用 ES Module。

1. 命名导出

utils.js:

javascript 复制代码
export function add(a, b) {
  return a + b;
}

export const API_URL = "/api";

其他文件导入:

csharp 复制代码
import { add, API_URL } from "./utils.js";

2. 默认导出

TaskList.js:

javascript 复制代码
export default function TaskList() {
  return "任务列表";
}

导入:

javascript 复制代码
import TaskList from "./TaskList.js";

区别:

类型 导出 导入
命名导出 export const a import { a }
默认导出 export default a import a

一个模块可以有多个命名导出,但最多只有一个默认导出。

React 项目中经常使用:

javascript 复制代码
import React from "react";
import { useState, useEffect } from "react";

十一、DOM 与事件:JavaScript 如何操作 HTML?

HTML:

bash 复制代码
<button id="addBtn">新增任务</button>

JavaScript:

javascript 复制代码
const button = document.getElementById("addBtn");

button.addEventListener("click", () => {
  console.log("新增任务");
});

事件监听中的箭头函数就是回调函数。

特别注意:

less 复制代码
// 正确:传递函数
button.addEventListener("click", handleClick);

// 错误用法:立即执行函数并传入返回值
button.addEventListener("click", handleClick());

如果需要传递参数:

scss 复制代码
button.addEventListener("click", () => {
  handleClick(123);
});

这个知识点可以直接迁移到 React 的 onClick。


十二、React 中最常见的 JavaScript 语法组合

假设现在需要开发一个任务管理页面。

javascript 复制代码
import { useState } from "react";

export default function TaskPage() {
  const [tasks, setTasks] = useState([
    { id: 1, name: "任务A", status: "running" },
    { id: 2, name: "任务B", status: "failed" }
  ]);

  // 筛选运行中的任务
  const runningTasks = tasks.filter(
    task => task.status === "running"
  );

  // 新增任务
  const addTask = () => {
    const newTask = {
      id: Date.now(),
      name: "新任务",
      status: "running"
    };

    setTasks(prev => [...prev, newTask]);
  };

  // 删除任务
  const deleteTask = (id) => {
    setTasks(prev =>
      prev.filter(task => task.id !== id)
    );
  };

  return (
    <div>
      <h2>任务管理</h2>

      <p>运行中:{runningTasks.length}</p>

      <button onClick={addTask}>
        新增任务
      </button>

      {tasks.map(task => (
        <div key={task.id}>
          <span>{task.name}</span>

          <button
            onClick={() => deleteTask(task.id)}
          >
            删除
          </button>
        </div>
      ))}
    </div>
  );
}

这里几乎覆盖了 React 中最常用的 JavaScript 语法:

代码 对应知识点
const 变量声明
{ id, name } 对象
[tasks, setTasks] 数组解构
task => ... 箭头函数
filter() 数组过滤
map() 数组映射
...prev 展开运算符
!== 严格不等
onClick={addTask} 函数作为回调
import / export ES Module

因此,真正进入 React 开发之后,你会发现大量代码都围绕这些基础 JavaScript 语法展开。


十三、需要了解但可以后学的知识

1. 闭包(Closure)

javascript 复制代码
function createCounter() {
  let count = 0;

  return function() {
    count++;
    return count;
  };
}

const counter = createCounter();

console.log(counter()); // 1
console.log(counter()); // 2

内部函数可以持续访问外部函数作用域中的变量,这就是闭包的重要表现。

React Hooks 与闭包关系密切,后续需要进一步理解。

2. this

javascript 复制代码
const user = {
  name: "Kevin",

  sayHello() {
    console.log(this.name);
  }
};

user.sayHello(); // Kevin

普通函数中的 this 通常取决于调用方式。

箭头函数则没有自己的 this,而是从外层词法作用域获取。

3. class

javascript 复制代码
class User {
  constructor(name) {
    this.name = name;
  }

  sayHello() {
    console.log(this.name);
  }
}

const user = new User("Kevin");

user.sayHello();

现代 React 更常使用函数组件,因此 class 基础了解即可,后续根据项目需求深入。


十四、总结:JavaScript 应该如何快速学习?

对于 React + TypeScript 中后台开发,建议按这个顺序:

第一阶段:基础语法

  • const、let
  • 数据类型
  • 对象和数组
  • 条件与循环
  • 箭头函数

第二阶段:现代 JavaScript 核心

  • 解构赋值
  • 展开运算符
  • 可选链 ?.
  • 空值合并 ??
  • map、filter、find、reduce
  • 回调函数

第三阶段:前端工程必备

  • Promise
  • async/await
  • import/export
  • DOM 与事件

第四阶段:深入理解

  • 闭包
  • this
  • 原型链
  • 事件循环
  • JavaScript 内存机制

最后记住

对于已经掌握其他编程语言的工程师,JavaScript 不需要从最基础的循环、判断反复练习。

真正值得重点掌握的是:

箭头函数 + 数组操作 + 对象解构 + 展开运算符 + Promise/async-await + ES Module。

掌握这些内容后,就具备了阅读大部分 React 业务代码所需的 JavaScript 语法基础。

相关推荐
wangruofeng2 小时前
写给开发者的〈重构 UI〉实战笔记:从改好一个设置页开始,告别“程序员审美”
前端·aigc
程序员鱼皮2 小时前
格局!刚刚 DeepSeek 正式开放全家桶 API,咱都能复刻 DeepSeek App 了?
前端·aigc·ai编程
ZhengEnCi2 小时前
登录页电脑端怎么设计才不空:5 种布局方案与可粘贴 AI 提示词
前端·css·设计
Penge6662 小时前
JavaScript:DOM 树
前端
Penge6663 小时前
CSS 核心布局指南:盒模型、Flex 布局与 Position 定位
前端
Penge6664 小时前
HTML基础:HTML 标签属性
前端
Penge6664 小时前
HTML 基础:块级元素、行内元素与行内块元素详解
前端
Penge6664 小时前
前端基础:html语义化
前端
用户30816998764855 小时前
同一个端口能被两个程序监听吗?TCP 11 组绑定实测
前端