JavaScript基础详解

O泡李华 9

JavaScript 基础详解

本章位置:Java 核心阶段 Web 基础
前置知识:HTML、CSS
下一阶段:Java 核心框架
学习目标:掌握 JavaScript 基础语法、变量、数据类型、运算符、流程控制、函数、对象、数组、DOM、事件、表单、BOM、JSON、定时器与异步请求,为后续 Servlet、JSP、Vue 和前后端交互打基础。


一、JavaScript 是什么

JavaScript 是一种:

运行在浏览器中的脚本语言

它主要负责:

网页交互
数据处理
DOM 操作
表单校验
事件处理
网络请求

可以简单理解:

HTML
负责结构

CSS
负责样式

JavaScript
负责行为

二、JavaScript 能做什么

例如:

点击按钮弹出提示
切换菜单
表单校验
修改页面文字
动态增加表格数据
发送 AJAX 请求
调用后端接口
处理 JSON 数据

后面学习 Vue 时:

JavaScript 是核心基础

三、JavaScript 在哪里运行

最常见:

浏览器

现代 JavaScript 也可以运行在:

Node.js

环境中。

当前阶段主要学习:

浏览器 JavaScript

四、JavaScript 三种引入方式

常见:

行内
内部
外部

五、行内 JavaScript

例如:

<button onclick="alert('你好')">
    点击
</button>

不推荐大量使用。

原因:

HTML 和 JS 混在一起
不方便维护

六、内部 JavaScript

<script>
    console.log("Hello JavaScript");
</script>

通常放在:

body 底部

或者合理使用:

defer

七、外部 JavaScript

HTML:

<script src="js/app.js"></script>

app.js:

console.log("Hello JavaScript");

实际项目更推荐:

外部 JS 文件

八、defer

例如:

<script src="app.js" defer></script>

表示:

HTML 继续解析
JS 下载完成后
等 HTML 解析完成再执行

九、console.log()

console.log("Hello");

浏览器:

F12
→ Console

查看。


十、变量

现代 JavaScript 重点掌握:

let
const

let

let age = 20;

age = 21;

const

const name = "张三";

不能重新赋值:

name = "李四";

十一、默认优先 const

推荐:

默认 const
需要重新赋值时 let
尽量少用 var

十二、数据类型

常见:

number
string
boolean
undefined
null
bigint
symbol
object

十三、number

const age = 20;

const price = 19.9;

JavaScript 不像 Java 区分:

int
long
float
double

普通数字主要统一为:

number

十四、字符串

const name = "张三";

const city = '北京';

十五、模板字符串

const name = "张三";

const age = 20;

const text =
    `我叫 ${name},今年 ${age} 岁`;

console.log(text);

相比字符串拼接更清晰。


十六、boolean

const login = true;

const disabled = false;

十七、undefined

let value;

console.log(value);

结果:

undefined

十八、null

const user = null;

表示:

主动表示没有值

十九、typeof

console.log(
    typeof 123
);

console.log(
    typeof "Java"
);

结果:

number
string

二十、typeof null

typeof null

结果:

object

这是历史遗留行为。

判断 null 应写:

value === null

二十一、运算符

常见:

+
-
*
/
%
**

以及:

>
<
>=
<=
==
===
!=
!==
&&
||
!

二十二、== 和 ===

1 == "1"

结果:

true

因为会做隐式类型转换。

而:

1 === "1"

结果:

false

现代 JavaScript 推荐:

优先使用 === 和 !==

二十三、可选链 ?.

const name =
    user?.profile?.name;

如果中间对象不存在:

返回 undefined

不会直接报错。


二十四、空值合并 ??

const name =
    userName ?? "游客";

只有左边是:

null
undefined

时才使用右边默认值。


二十五、if

if (score >= 60) {

    console.log("及格");
}

二十六、if-else

if (age >= 18) {

    console.log("成年人");

} else {

    console.log("未成年人");
}

二十七、else if

if (score >= 90) {

    console.log("优秀");

} else if (score >= 80) {

    console.log("良好");

} else if (score >= 60) {

    console.log("及格");

} else {

    console.log("不及格");
}

二十八、switch

switch (status) {

    case 1:
        console.log("待支付");
        break;

    case 2:
        console.log("已支付");
        break;

    default:
        console.log("未知状态");
}

二十九、for

for (
    let i = 0;
    i < 10;
    i++
) {

    console.log(i);
}

三十、while

let i = 0;

while (i < 10) {

    console.log(i);

    i++;
}

三十一、函数

function add(
    a,
    b
) {

    return a + b;
}

调用:

const result =
    add(10, 20);

三十二、箭头函数

const add =
    (
        a,
        b
    ) => {

        return a + b;
    };

简写:

const add =
    (a, b) =>
        a + b;

三十三、对象

const student = {

    name:
        "张三",

    age:
        20,

    score:
        90
};

访问:

student.name

或:

student["name"]

三十四、对象方法

const student = {

    name:
        "张三",

    study() {

        console.log(
            "正在学习"
        );
    }
};

student.study();

三十五、数组

const numbers =
    [
        10,
        20,
        30
    ];

访问:

numbers[0]

长度:

numbers.length

三十六、数组常用方法

尾部添加:

numbers.push(40);

尾部删除:

numbers.pop();

头部添加:

numbers.unshift(0);

头部删除:

numbers.shift();

三十七、slice()

const result =
    numbers.slice(
        1,
        3
    );

特点:

左闭右开
不修改原数组

三十八、splice()

删除:

numbers.splice(
    1,
    1
);

splice() 会修改原数组。


三十九、includes()

numbers.includes(20);

返回:

true / false

四十、for…of

for (
    const value
    of numbers
) {

    console.log(value);
}

适合遍历数组值。


四十一、forEach()

numbers.forEach(
    value => {

        console.log(value);
    }
);

四十二、map()

const result =
    numbers.map(
        value =>
            value * 2
    );

生成新数组。


四十三、filter()

const scores =
    [
        50,
        80,
        90,
        40
    ];

const passed =
    scores.filter(
        score =>
            score >= 60
    );

结果:

[80, 90]

四十四、find()

const student =
    students.find(
        item =>
            item.id === 2
    );

四十五、some() 和 every()

const hasFail =
    scores.some(
        score =>
            score < 60
    );
const allPassed =
    scores.every(
        score =>
            score >= 60
    );

四十六、reduce()

求和:

const total =
    numbers.reduce(
        (
            sum,
            value
        ) =>
            sum + value,
        0
    );

四十七、sort()

数字升序:

numbers.sort(
    (
        a,
        b
    ) =>
        a - b
);

数字降序:

numbers.sort(
    (
        a,
        b
    ) =>
        b - a
);

注意:

sort() 会修改原数组

四十八、解构

对象:

const {
    name,
    age
} = student;

数组:

const [
    first,
    second
] = numbers;

四十九、展开运算符

数组:

const copy =
    [
        ...numbers
    ];

对象:

const newStudent = {
    ...student,
    score:
        100
};

注意:

这是浅拷贝

五十、JSON

JSON 是前后端开发非常重要的数据格式。

{
    "id": 1,
    "name": "张三",
    "age": 20
}

五十一、JSON.stringify()

对象转 JSON 字符串:

const json =
    JSON.stringify(
        student
    );

五十二、JSON.parse()

const student =
    JSON.parse(
        json
    );

五十三、DOM

DOM:

Document Object Model

浏览器把 HTML 解析成对象树,

JavaScript 可以:

查找
修改
创建
删除

页面元素。


五十四、querySelector()

HTML:

<h1 id="title">
    Hello
</h1>

JS:

const title =
    document
        .querySelector(
            "#title"
        );

五十五、querySelectorAll()

const items =
    document
        .querySelectorAll(
            ".item"
        );

五十六、textContent

title.textContent =
    "新的标题";

适合设置普通文本。


五十七、innerHTML

container.innerHTML =
    "<strong>Hello</strong>";

会解析 HTML。

注意:

不要把不可信用户输入直接放进 innerHTML,否则可能产生 XSS 风险。

普通文本优先:

textContent

五十八、classList

添加:

element.classList.add(
    "active"
);

删除:

element.classList.remove(
    "active"
);

切换:

element.classList.toggle(
    "active"
);

五十九、创建元素

const li =
    document
        .createElement(
            "li"
        );

li.textContent =
    "Java";

添加:

list.append(li);

删除:

li.remove();

六十、事件

常见:

click
input
change
submit
keydown
mouseover

六十一、addEventListener()

button.addEventListener(
    "click",
    () => {

        console.log(
            "按钮被点击"
        );
    }
);

六十二、事件对象

button.addEventListener(
    "click",
    event => {

        console.log(
            event.target
        );
    }
);

六十三、表单提交

form.addEventListener(
    "submit",
    event => {

        event.preventDefault();

        console.log(
            "自己处理表单"
        );
    }
);

六十四、获取 input 值

const username =
    document
        .querySelector(
            "#username"
        )
        .value
        .trim();

六十五、表单校验

if (
    username === ""
) {

    alert(
        "用户名不能为空"
    );

    return;
}

注意:

前端校验不能替代后端校验

六十六、正则

const regex =
    /^\d{6}$/;

console.log(
    regex.test(
        "123456"
    )
);

六十七、BOM

BOM:

Browser Object Model

常见:

window
location
history
navigator

六十八、location

跳转:

location.href =
    "https://example.com";

刷新:

location.reload();

六十九、定时器

延迟执行:

setTimeout(
    () => {

        console.log(
            "3 秒后执行"
        );
    },
    3000
);

重复执行:

const timer =
    setInterval(
        () => {

            console.log(
                "每秒执行"
            );
        },
        1000
    );

停止:

clearInterval(
    timer
);

七十、Date

const now =
    new Date();

获取年份:

now.getFullYear();

月份:

now.getMonth()
+ 1;

注意:

getMonth() 是 0~11

七十一、Math

Math.max(
    10,
    20
);

Math.min(
    10,
    20
);

Math.random();

Math.floor(
    3.9
);

随机 1~10:

const number =
    Math.floor(
        Math.random()
        * 10
    )
    + 1;

七十二、类型转换

字符串转数字:

Number(
    "123"
);

整数:

parseInt(
    "123"
);

浮点:

parseFloat(
    "3.14"
);

七十三、NaN

const value =
    Number(
        "abc"
    );

结果:

NaN

推荐:

Number.isNaN(
    value
);

七十四、localStorage

保存:

localStorage.setItem(
    "username",
    "admin"
);

读取:

const username =
    localStorage.getItem(
        "username"
    );

删除:

localStorage.removeItem(
    "username"
);

七十五、保存对象到 localStorage

const user = {
    id: 1,
    name:
        "张三"
};

localStorage.setItem(
    "user",
    JSON.stringify(
        user
    )
);

读取:

const user =
    JSON.parse(
        localStorage.getItem(
            "user"
        )
    );

七十六、Promise

Promise 表示:

未来可能完成或失败的异步结果

状态:

pending
fulfilled
rejected

七十七、Promise 基础

const promise =
    new Promise(
        (
            resolve,
            reject
        ) => {

            const success =
                true;

            if (success) {

                resolve(
                    "成功"
                );

            } else {

                reject(
                    new Error(
                        "失败"
                    )
                );
            }
        }
    );

七十八、then / catch

promise
    .then(
        result => {

            console.log(
                result
            );
        }
    )
    .catch(
        error => {

            console.error(
                error
            );
        }
    );

七十九、async / await

async function loadData() {

    const result =
        await promise;

    console.log(result);
}

八十、fetch()

发送 HTTP 请求:

fetch(
    "/api/students"
);

返回:

Promise

八十一、GET 请求

async function loadStudents() {

    const response =
        await fetch(
            "/api/students"
        );

    if (
        !response.ok
    ) {

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

    const data =
        await response.json();

    console.log(data);
}

八十二、POST JSON

async function addStudent(
    student
) {

    const response =
        await fetch(
            "/api/students",
            {
                method:
                    "POST",

                headers: {
                    "Content-Type":
                        "application/json"
                },

                body:
                    JSON.stringify(
                        student
                    )
            }
        );

    if (
        !response.ok
    ) {

        throw new Error(
            "新增失败"
        );
    }

    return response.json();
}

八十三、前后端交互流程

用户操作页面
↓
JavaScript 获取数据
↓
组装对象
↓
JSON.stringify
↓
fetch
↓
HTTP 请求
↓
Java 后端
↓
数据库
↓
返回 JSON
↓
JavaScript
↓
修改 DOM

这就是后面:

Servlet
SpringBoot
Vue

会反复使用的流程。


八十四、综合案例:学生列表

数据:

const students = [
    {
        id: 1,
        name:
            "张三",
        score:
            90
    },
    {
        id: 2,
        name:
            "李四",
        score:
            85
    }
];

HTML:

<table>

    <thead>

        <tr>
            <th>ID</th>
            <th>姓名</th>
            <th>成绩</th>
        </tr>

    </thead>

    <tbody id="student-body">
    </tbody>

</table>

八十五、渲染学生表格

function renderStudents(
    students
) {

    const tbody =
        document
            .querySelector(
                "#student-body"
            );

    tbody.textContent =
        "";

    for (
        const student
        of students
    ) {

        const tr =
            document
                .createElement(
                    "tr"
                );

        const idTd =
            document
                .createElement(
                    "td"
                );

        idTd.textContent =
            student.id;

        const nameTd =
            document
                .createElement(
                    "td"
                );

        nameTd.textContent =
            student.name;

        const scoreTd =
            document
                .createElement(
                    "td"
                );

        scoreTd.textContent =
            student.score;

        tr.append(
            idTd,
            nameTd,
            scoreTd
        );

        tbody.append(
            tr
        );
    }
}

八十六、学生搜索

const keyword =
    "张";

const result =
    students.filter(
        student =>
            student.name
                .includes(
                    keyword
                )
    );

八十七、学生排行榜

const ranking =
    [
        ...students
    ].sort(
        (
            a,
            b
        ) =>
            b.score
            - a.score
    );

先复制再排序:

避免 sort() 直接改变原数组

八十八、常见错误:使用 ==

推荐:

===

而不是:

==

八十九、常见错误:const 对象完全不能修改

const user = {
    name:
        "张三"
};

user.name =
    "李四";

这是允许的。

不能:

user = {};

九十、常见错误:数字数组直接 sort()

错误:

[
    2,
    10,
    1
].sort();

数字升序:

numbers.sort(
    (
        a,
        b
    ) =>
        a - b
);

九十一、常见错误:innerHTML 放用户输入

危险:

result.innerHTML =
    userInput;

普通文本优先:

result.textContent =
    userInput;

九十二、常见错误:只做前端校验

JavaScript 校验:

主要提升用户体验

真正数据安全必须:

Java 后端再次校验

九十三、常见错误:fetch 不检查 response.ok

推荐:

if (
    !response.ok
) {

    throw new Error(
        "请求失败"
    );
}

因为:

404 / 500
不一定让 fetch Promise 自动 reject

九十四、常见错误:不理解异步执行

错误思路:

let data;

fetch(
    "/api/data"
)
.then(
    response =>
        response.json()
)
.then(
    result => {

        data =
            result;
    }
);

console.log(data);

这里很可能先打印:

undefined

因为网络请求还没有完成。


九十五、浏览器调试

按:

F12

重点:

Console
Sources
Network
Elements

九十六、Network 面板

后面前后端联调必须会看:

Request URL

Request Method

Status Code

Request Headers

Request Payload

Response

九十七、JavaScript 必须掌握的语法

let
const
数据类型
===
if
switch
for
while
函数
箭头函数
对象
数组
解构
展开运算符

九十八、数组方法必须熟练

push()

pop()

slice()

splice()

includes()

forEach()

map()

filter()

find()

some()

every()

reduce()

sort()

九十九、DOM 必须掌握

document.querySelector()

document.querySelectorAll()

textContent

classList

createElement()

append()

remove()

value

一百、事件必须掌握

addEventListener()

click

input

change

submit

preventDefault()

event.target

一百零一、异步基础必须掌握

Promise

then

catch

async

await

fetch

response.ok

response.json()

一百零二、练习题

建议完成:

1. 成绩等级判断

2. 数组求和和平均值

3. filter 筛选及格成绩

4. 对象数组按成绩排序

5. 点击按钮修改标题

6. 动态新增 li

7. 删除列表项

8. 登录表单校验

9. 60 秒验证码倒计时

10. localStorage 保存昵称

11. JSON 对象互转

12. fetch 获取列表数据

13. fetch POST 提交 JSON

14. 学生列表搜索

15. 学生排行榜页面

一百零三、Java 和 JavaScript 不要混淆

虽然名字相似:

Java
JavaScript

但完全是两门不同语言。

Java:

静态类型
服务端开发常用

JavaScript:

动态类型
浏览器前端核心

JavaScript 不是:

Java 的简化版

一百零四、第一阶段知识路线总结

到这里,第一阶段已经形成:

Java 开发环境
↓
变量和运算符
↓
选择和循环
↓
数组
↓
面向对象
↓
常用类
↓
异常
↓
集合
↓
IO
↓
多线程
↓
数据库基础
↓
JDBC / DAO
↓
综合项目
↓
HTML / CSS
↓
JavaScript

一百零五、本章总结

JavaScript 的核心路线:

变量
↓
流程控制
↓
函数
↓
对象
↓
数组
↓
DOM
↓
事件
↓
表单
↓
JSON
↓
Promise
↓
async / await
↓
fetch

后面进入 Java Web 后:

JavaScript
负责页面交互和请求

Java
负责业务处理和数据库操作

两边通过:

HTTP + JSON

通信。

掌握这一章以后,你就完成了课程体系中的:

第一阶段:Java 核心

接下来正式进入:

第二阶段:Java 核心框架