JavaScript入门指南:从零开始掌握网页交互

一、初识JavaScript

1.1 JavaScript是什么?

JavaScript(简称JS)是一门跨平台面向对象脚本语言,核心作用是控制网页行为,让静态页面动起来。

  • 运行环境 :主要在客户端 (浏览器),也可通过Node.js运行在服务器端
  • 核心版 本:ES6(ECMAScript 2015)是目前最常用的版本,新增了大量实用语法

三个核心特点:

客户端运行 :在用户浏览器中直接执行,无需服务器处理

脚本语言 :不需要编译,由浏览器直接解释执行

面向对象:支持面向对象编程,代码更易组织

1.2 JavaScript的组成

JS不是单一语法,而是由三部分组成,各司其职:

  1. ECMAScript:JS的基础语法核心,规定了变量、函数、数据类型等基础规则,是所有JS环境的通用标准
  2. Web APIs:分为DOM和BOM,是JS操作网页和浏览器的接口
    • DOM(文档对象模型):操作网页元素(如修改文字、样式、添加标签)
    • BOM(浏览器对象模型):操作浏览器(如跳转页面、弹出弹窗、获取地址栏)

1.3 JS的3种书写位置

方式1: 内部JavaScript(写在HTML里)

<script>标签包裹代码,可放在HTML的或中,推荐放在闭合标签上方。

bash 复制代码
<!DOCTYPE html>
<html>
<body>
  <h1>我的网页</h1>
  
  <!-- 推荐放在body结束前, 避免JS执行时html还没加载完 -->
  <script>
    alert("Hello JavaScript!");
  </script>
</body>
</html>

注意

<script>标签不能自闭合(不能写成<script/>);

② 放底部是因为浏览器按顺序加载HTML,若JS先加载且要操作下方HTML,会因HTML未加载而失效

方式2:外部JavaScript(实际项目常用)

将代码写在.js后缀的文件中,再通过<script>标签的src属性引入HTML,是开发中最推荐的方式(代码复用性高、HTML更简洁)。

bash 复制代码
<!-- index.html -->
<body>
  <script src="app.js"></script>
</body>

<!-- app.js -->
console.log("这是外部JS文件");

注意

① 引入外部JS的<script>标签中间不能写代码,写了也会被忽略;

② 多个外部JS按引入顺序执行。

方式3:内联JavaScript(写在标签内部,了解即可)

将代码直接写在HTML标签的事件属性中,仅作了解,后续Vue框架会用到类似写法。

bash 复制代码
<body>
  <!-- 点击按钮弹出提示框 -->
  <button onclick="alert('逗你玩~~~')">点击我月薪过万</button>
</body>

1.4 JS注释:代码的"说明书"

注释是给开发者看的文字,浏览器会忽略,用于标注代码功能,方便后续维护。

注释类型 符号 作用 快捷键
单行注释 // 注释当前行内容 Ctrl + /
块注释 /* */ 注释多行内容(可跨行) Shift + Alt + A
bash 复制代码
// 这是单行注释
console.log("hello"); // 注释也可以写在代码后面

/*
  多行注释
  可以写很多行
*/

/**
 * 文档注释(常用)
 * 说明函数功能
 * @param {number} x - 参数说明
 */

1.5 JS结束符:分号用不用?

用英文分号;表示一条语句结束,实际开发中可加可不加 ,浏览器会自动推断语句结束位置。
约定风格统一最重要,要么每句都加,要么每句都不加(按团队要求来),避免混用。

bash 复制代码
// 方式1:每行都加(严谨)
console.log("Hello");
let name = "小明";

// 方式2:不加分号(现代风格)
console.log("Hello")
let name = "小明"

1.6 JS输入输出:和用户交互

输入输出是人与计算机的交互:用户输入信息(如键盘输入),计算机处理后展示结果(如弹窗、控制台打印)。

输出语法(向用户展示内容)

语法 作用 示例
document.write('内容') 向网页body中输出内容,支持HTML标签 document.write('<h2>我是输出的标题</h2>')
alert('内容') 弹出警告对话框,阻断页面执行 alert('欢迎来到JS世界')
console.log('内容') 向浏览器控制台打印内容,供开发者调试 console.log('调试信息')

输入语法(获取用户信息)

bash 复制代码
// 弹出输入框,提示用户输入姓名,返回值是用户输入的内容
var name = prompt('请输入您的姓名:');
// 将输入的姓名打印到控制台
console.log('用户姓名:', name);

代码执行顺序

  • 默认按HTML文档流顺序执行(从上到下)
  • alert()prompt()会跳过页面渲染优先执行(先弹窗,再加载页面内容)

1.7 字面量:描述具体的数据

字面量是直接表示具体值 的语法,相当于"数据的字面形式",用来描述事物的具体内容。

bash 复制代码
// 数字字面量(表示具体数字)
var salary = 1000; 
// 字符串字面量(表示具体文本,用单/双引号包裹)
var company = '黑马程序员';
// 后续会学的其他字面量
var arr = [1,2,3]; // 数组字面量
var obj = {name: '张三'}; // 对象字面量

二、JS基础语法:变量、数据类型与运算符

2.1 核心概念:内存、数据、变量

  • 数据:存储在内存中的信息(本质是二进制0101),程序所有操作的目标都是数据(万物皆数据,函数也是数据)。
  • 内存:内存条通电后产生的临时存储空间,断电后数据消失(与硬盘的持久存储不同)。声明变量/函数时,JS引擎会自动分配内存,不用手动管理。
  • 变量:值可以变化的量,是内存的"标识"------通过变量名找到对应的内存,进而操作内存中的数据(一个变量对应一块小内存)。

三者关系:内存是"容器",数据是"容器里的东西",变量是"容器的标签"。

2.2 变量:存储数据的容器

变量的定义格式

bash 复制代码
// 1. var - 老方法(不推荐)
// 只声明变量,不赋值(默认值为undefined)
var age;
// 声明并赋值(推荐)
var name = '张三';
// 同时声明多个变量
var height = 180, weight = 70;

// 2. let - 现代方法(推荐)
let age = 18;
age = 19;        // 可以重新赋值
// let age = 20; // 错误!不能重复声明

// 3. const - 声明常量
const PI = 3.14;
// PI = 3.15;    // 错误!常量不能修改

JS是弱类型语言:变量没有固定类型,可随时存储不同类型的值(如先存数字,再存字符串)。

var、let、const的区别(ES6特性)
ES6新增letconst,解决了var的一些问题,实际开发中优先用let/const

关键字 作用域 是否可重复声明 是否可修改值 适用场景
var 全局/函数作用域(代码块内声明也能被外部访问) 兼容旧环境,现在很少用
let 块级作用域(仅在所在代码块内有效) 值会变化的变量
const 块级作用域 否(声明时必须赋值) 值固定的常量(如PI、接口地址)

变量命名规范

  • 由字母、数字、下划线(_)、美元符号($)组成,不能以数字开头
  • 区分大小写(name和Name是两个不同变量)
  • 不能用JS关键字(如var、function、if等)
  • 推荐用驼峰命名法:首字母小写,后续单词首字母大写(如userName、totalPrice)

命名规范示例

bash 复制代码
// ✅ 正确命名
let userName = "小明";     // 驼峰命名法
let isLogin = true;       // 布尔值用is开头
let MAX_COUNT = 100;      // 常量全大写

// ❌ 错误命名
let 1name = "";           // 不能数字开头
let user-name = "";       // 不能用短横线
let function = "";        // 不能用关键字

2.3 数据类型:JS中的"数据分类"

JS将数据分为两大类:基本类型(值类型)对象类型(引用类型),不同类型的存储和操作方式不同。

(1)基本数据类型(5种)

直接存储值,占用空间小,存放在内存栈中。

类型 描述 示例
String 任意字符串(单/双引号、反引号包裹) 'hello'、"world"、姓名:${name}
Number 任意数字(整数、小数、NaN),NaN表示"非数字" 100、3.14、NaN(typeof NaN === 'number')
Boolean 布尔值,仅两个值:true(真)、false(假) true、false
Undefined 变量声明未赋值时的默认值 var age; // age的值是undefined
Null 表示"空对象",主动赋值表示值为空 var obj = null; // 表示obj后续会存对象

注意 :大数值精度问题

JS中数字 默认是双精度浮点数,能安全表示的整数范围是 -2⁵³+1 ~ 2⁵³-1(约±9e15),超过这个范围会丢失精度。

bash 复制代码
// 大数值丢失精度示例
console.log(Number("898186844400803840")); // 输出898186844400803800(末尾40变成00)

解决方案:

  • 用字符串存储大数值,避免转为Number类型
  • 若必须处理数值型大数值,用第三方库(如lossless-jsonjson-bigint

基本数据类型赋值示例

bash 复制代码
// 1. String - 字符串
let name = "JavaScript";
let greeting = 'Hello';
let message = `模板字符串${name}`;  // ES6新特性

// 2. Number - 数字
let age = 25;
let price = 99.99;
let bigNum = 1e6;  // 1000000(科学计数法)

// 3. Boolean - 布尔值
let isStudent = true;
let isWorking = false;

// 4. Undefined - 未定义
let x;  // undefined
let y = undefined;

// 5. Null - 空值
let empty = null;

(2)对象数据类型(引用类型)

存储的是内存地址(指向堆中的数据),占用空间大,适合存储复杂数据。

类型 描述 示例
Object 通用对象,存储键值对数据 {name: '张三', age: 20}
Function 特殊对象,可执行代码 function sum(a,b){return a+b}
Array 特殊对象,按索引存储有序数据 [1,2,3,4]

引用数据类型示例

bash 复制代码
// 1. Object - 对象
let person = {
  name: "小明",
  age: 18,
  sayHello: function() {
    console.log("你好!");
  }
};

// 2. Array - 数组
let colors = ["red", "green", "blue"];

// 3. Function - 函数
function add(a, b) {
  return a + b;
}

(3)数据类型判断方法

方法 适用场景 局限性 示例
typeof 判断基本类型(undefined、Number、String、Boolean) 无法区分Null和Object、Object和Array(typeof null === 'object'是历史bug) typeof 'hello' → 'string'
instanceof 判断对象的具体类型 不能判断基本类型 [1,2] instanceof Array → true
===(全等于) 判断undefinednull 仅适用于这两种类型 age === undefined → true

补充:undefined与null的区别

  • undefined:变量声明但未赋值(默认值)
  • null:变量声明且赋值,但值为空(主动表示"无对象")

赋值场景

① 初始赋值为null,表示变量后续会存对象;

② 函数结束前将对象赋值为null,让其成为垃圾对象(被回收)。

类型判断示例

bash 复制代码
// 常用判断方法
typeof "hello"      // "string"
typeof 123          // "number"
typeof true         // "boolean"
typeof undefined    // "undefined"
typeof null         // "object"(历史遗留问题)

// 准确判断
Array.isArray([])           // true(判断数组)
[] instanceof Array         // true
Object.prototype.toString.call(null)  // "[object Null]"
Object.prototype.toString.call([]) // "[object Array]"

2.4 运算符:JS中的"计算工具"

(1)关系运算符(比较运算)

用于比较两个值的关系,返回布尔值(true/false),核心区分=====

运算符 规则 示例 结果
==(等于) 先做类型转换,再比较值 "12" == 12 true
===(全等于) 不做类型转换,同时比较值和类型 "12" === 12 false

开发中优先用===,避免类型转换导致的意外结果。

(2)逻辑运算符(与、或、非)

用于逻辑判断,支持"短路运算"(满足条件后不再执行后续代码)。

运算符 名称 短路规则 示例 结果
& 逻辑与 遇假则停,返回第一个假值;全为真返回最后一个真值 3 && 0 && 5 0
或(表示双竖杠) 逻辑或 遇真则停,返回第一个真值;全为假返回最后一个假值 0 或 3 或5 3
! 逻辑非 取反布尔值(真变假,假变真) !true false

运算符示例

bash 复制代码
//算术运算符
let a = 10, b = 3;

a + b      // 13(加)
a - b      // 7(减)
a * b      // 30(乘)
a / b      // 3.333...(除)
a % b      // 1(取余)
a ** b     // 1000(指数,ES7)

//比较运算符
5 == "5"      // true(值相等)
5 === "5"     // false(值和类型都相等)
5 != "5"      // false
5 !== "5"     // true

10 > 5        // true
10 >= 10      // true

//逻辑运算符
// &&(与)- 全为真才为真
true && true      // true
true && false     // false

// ||(或)- 有一个为真就为真
true || false     // true
false || false    // false

// !(非)- 取反
!true             // false
!false            // true

// 短路运算(常用技巧)
let name = user && user.name;  // user存在才取name
let count = value || 0;        // value为假时用0

2.5 类型转换:不同类型数据的转换

JS中运算或判断时,常会自动转换数据类型隐式转换),也可手动转换显式转换)。

(1)转换为字符串

bash 复制代码
var num = 123;
// 1. toString()方法(null和undefined不能用)
var str1 = num.toString();
// 2. String()强制转换(所有类型都能用)
var str2 = String(num);
// 3. toLocaleString()(数字转千分位字符串)
var str3 = num.toLocaleString(); // "123"(大数字如1234567 → "1,234,567")
// 4. 隐式转换(+拼接字符串)
var str4 = num + "";

(2)转换为数字型(重点)

bash 复制代码
var str = "123";
// 1. parseInt():解析为整数(遇到非数字字符停止)
var num1 = parseInt(str); // 123
var num2 = parseInt("123a"); // 123
var num3 = parseInt("a123"); // NaN
// 2. parseFloat():解析为浮点数(支持小数点)
var num4 = parseFloat("123.45"); // 123.45
// 3. Number():强制转换(整体转换,非数字则为NaN)
var num5 = Number(str); // 123
var num6 = Number("123a"); // NaN
// 4. 隐式转换(-、*、/运算)
var num7 = str - 0; // 123
// 5. +号隐式转换
var num8 = +str; // 123

(3)转换为布尔值

以下值转换为布尔值为false(假值),其余均为true(真值):0、NaN、""(空串)、null、undefined。

bash 复制代码
// 显式转换
console.log(Boolean(0)); // false
console.log(Boolean("hello")); // true
// 隐式转换(逻辑运算、条件判断时)
if ("hello") { console.log("真值"); }

三、JS函数:封装可复用的代码块

函数是一组可重复执行的代码块,封装逻辑后可多次调用,减少代码冗余。

3.1 函数的两种定义方式

方式1:函数声明(function关键字定义)

bash 复制代码
// 定义函数
function 函数名(形参1, 形参2) {
  // 函数体(要执行的代码)
  return 返回值; // 可选,返回函数执行结果
}
// 调用函数(形参接收实参的值)
var 结果 = 函数名(实参1, 实参2);

// 示例:求和函数
function sum(a, b) {
  return a + b;
}
var total = sum(2, 3);
console.log(total); // 5

特点:形参无需指定类型,返回值无需定义类型,直接用return返回即可。

方式2:函数表达式(赋值给变量)

bash 复制代码
// 定义函数(匿名函数赋值给变量)
var 函数名 = function(形参列表) {
  函数体;
};
// 调用函数
函数名(实参列表);

// 示例
var sayHello = function(name) {
  console.log("Hello, " + name);
};
sayHello("张三"); // Hello, 张三

注意 :JS没有函数重载

Java中函数名相同、参数不同 视为重载,但JS中重复定义同名函数,后定义的会覆盖前定义的。

bash 复制代码
function sum(a) {
  return a + 1;
}
function sum(a, b) { // 覆盖前一个sum
  return a + b;
}
console.log(sum(2)); // NaN(第二个sum需要两个参数,b未赋值为undefined)

函数的作用域

bash 复制代码
let globalVar = "全局变量";  // 全局作用域

function testScope() {
  let localVar = "局部变量";  // 函数作用域
  
  if (true) {
    let blockVar = "块级变量";  // 块级作用域(ES6)
    console.log(blockVar);      // 可以访问
  }
  
  // console.log(blockVar);    // 错误!不能访问块级变量
}

console.log(globalVar);  // 可以访问
// console.log(localVar); // 错误!不能访问局部变量

3.2 arguments:隐形参数(处理不定参)

当不确定函数接收多少个实参时,用arguments(函数内置对象)获取所有实参,是一个"伪数组"。

伪数组特点

  • 有length属性,按索引存储数据
  • 没有数组的方法(如push、pop)
  • 仅能在函数内部使用

示例:求任意个数的和

bash 复制代码
function sum() {
  var total = 0;
  // 遍历arguments,累加所有实参
  for (var i = 0; i < arguments.length; i++) {
    total += arguments[i];
  }
  return total;
}
console.log(sum(1,2)); // 3
console.log(sum(1,2,3,4)); // 10

arguments转真数组

bash 复制代码
function fn() {
  // 方法1:Array.prototype.slice.call
  var arr1 = Array.prototype.slice.call(arguments);
  // 方法2:[].slice.call(简写)
  var arr2 = [].slice.call(arguments);
  console.log(arr1 instanceof Array); // true
}

四、JS对象:存储复杂数据的容器

对象是多个数据的集合体(封装体),用于统一管理关联数据,JS中对象分3类:自定义对象内置对象浏览器对象

内置对象是JS自带的对象(如Math、Date、Array),提供了常用功能,是开发核心;浏览器对象(BOM、DOM)用于操作浏览器和网页,后续详解。

4.1 内置对象 Math(数学计算)

Math不是构造函数,无需实例化,直接用Math.属性/方法调用,提供常用数学运算。

属性/方法 功能 示例 结果
Math.PI 圆周率 Math.PI 3.141592653589793
Math.floor(x) 向下取整(舍掉小数) Math.floor(3.8) 3
Math.ceil(x) 向上取整(进1) Math.ceil(3.2) 4
Math.round(x) 四舍五入(注意:-3.5返回-3) Math.round(3.5) 4
Math.abs(x) 绝对值 Math.abs(-5) 5
Math.max(x,y,...) 求最大值 Math.max(1,3,2) 3
Math.min(x,y,...) 求最小值 Math.min(1,3,2) 1
Math.random() 获取[0,1)之间的随机小数 Math.random() 0.123456...(随机)

实用示例:获取指定范围的随机整数

bash 复制代码
// 获取 [min, max] 范围内的随机整数(包含min和max)
function getRandom(min, max) {
  return Math.floor(Math.random() * (max - min + 1)) + min;
}
// 示例:获取1-10之间的随机数
console.log(getRandom(1, 10));

4.2 内置对象:Date(日期对象)

Date是构造函数,需实例化(new Date())才能使用,用于处理日期和时间。

(1)实例化Date对象

bash 复制代码
// 1. 无参数:获取当前时间
var now = new Date();
console.log(now); // 输出当前时间(如 Tue Jan 06 2026 13:57:10 GMT+0800 (中国标准时间)

// 2. 有参数:获取指定时间
var future1 = new Date('2026/12/31'); // 字符串格式
var future2 = new Date(2026, 11, 31); // 数字格式(月份0-11,11表示12月)
var future3 = new Date(2026, 11, 31, 23, 59, 59); // 年、月、日、时、分、秒

(2)获取日期时间的方法

方法 功能 示例(now为当前时间对象)
getFullYear() 获取年份(4位) now.getFullYear() → 2026
getMonth() 获取月份(0-11) now.getMonth() + 1 → 1(1月)
getDate() 获取日期(1-31) now.getDate() → 6
getDay() 获取星期(0-6,0为周日) now.getDay() → 3(周三)
getHours() 获取小时(0-23) now.getHours() → 10
getMinutes() 获取分钟(0-59) now.getMinutes() → 30
getSeconds() 获取秒数(0-59) now.getSeconds() → 45

(3)获取总毫秒数(时间戳)

时间戳是从1970年1月1日(世界标准时间)到指定时间的毫秒数,用于时间差计算。

bash 复制代码
var date = new Date();
// 方法1:valueOf()/getTime()
console.log(date.valueOf()); // 输出时间戳 1767679294424
console.log(date.getTime());

// 方法2:简写(隐式转换)
var timestamp1 = +new Date();

// 方法3:HTML5新增(有兼容性,推荐现代浏览器用)
var timestamp2 = Date.now();

格式化日期

bash 复制代码
now.toLocaleString()          // "2024/1/1 12:00:00"
now.toLocaleDateString()      // "2024/1/1"
now.toLocaleTimeString()      // "12:00:00"

4.3 内置对象:Array(数组对象)

数组是有序的集合,可存储任意类型数据长度可变(自动扩容),用于管理一组相关数据。

(1)创建数组的两种方式

bash 复制代码
// 方式1:字面量方式(推荐,简洁)
var arr1 = [1, 'test', true, null]; // 可存储不同类型数据

// 方式2:new Array()(构造函数)
var arr2 = new Array(); // 空数组
var arr3 = new Array(1,2,3,4); // 传入多个参数:数组元素
var arr4 = new Array(5); // 传入一个参数:数组长度(5个空元素)

(2)数组属性:length(长度)

bash 复制代码
var arr = [1,2,3];
console.log(arr.length); // 3
// 修改length可改变数组长度
arr.length = 5;
console.log(arr); // [1, 2, 3, 空属性 × 2](新增两个空元素)

(3)数组方法:检测是否为数组

bash 复制代码
var arr = [1,2,3];
var obj = {};

// 方法1:instanceof
console.log(arr instanceof Array); // true
console.log(obj instanceof Array); // false

// 方法2:Array.isArray()(HTML5新增,更可靠)
console.log(Array.isArray(arr)); // true
console.log(Array.isArray(obj)); // false

(4)数组方法:遍历数组

bash 复制代码
var arr = [1,2,3,4];

// 方法1:for循环(最灵活,可控制索引)
for (var i = 0; i < arr.length; i++) {
  console.log(arr[i]); // 1,2,3,4
}

// 方法2:for...in循环(遍历索引,适合对象/数组)
for (var k in arr) {
  console.log(arr[k]); // 1,2,3,4
}

// 方法3:forEach循环(数组专属,简洁)
arr.forEach(function(item) {
  console.log(item); // 1,2,3,4
});

// ES6箭头函数简写
arr.forEach(item => console.log(item));

(5)数组方法:添加/删除元素

方法 功能 是否修改原数组 返回值
push(参数1...) 在数组末尾添加元素 新数组长度
pop() 删除数组最后一个元素 被删除的元素
unshift(参数1...) 在数组开头添加一个或多个元素 新数组的长度
shift() 删除数组第一个元素,无参数 被删除的元素(数组为空时返回undefined)
bash 复制代码
// 示例1:push() 末尾添加
var arr = [1,2,3];
var len1 = arr.push(4, 'hello');
console.log(arr); // [1,2,3,4,'hello']
console.log(len1); // 5(返回新长度)

// 示例2:pop() 末尾删除
var delItem1 = arr.pop();
console.log(arr); // [1,2,3,4]
console.log(delItem1); // 'hello'(返回被删除元素)

// 示例3:unshift() 开头添加
var len2 = arr.unshift(0, 'test');
console.log(arr); // [0,'test',1,2,3,4]
console.log(len2); // 6(返回新长度)

// 示例4:shift() 开头删除
var delItem2 = arr.shift();
console.log(arr); // ['test',1,2,3,4]
console.log(delItem2); // 0(返回被删除元素)

(6)数组方法:数组转换与拼接

这类方法用于数组与字符串的转换、多个数组的合并,部分方法不修改原数组,需接收返回值使用。

方法 功能 是否修改原数组 返回值
join(分隔符) 将数组元素拼接为字符串,分隔符可选(默认逗号) 拼接后的字符串
concat(数组1,数组2...) 合并多个数组(或元素),生成新数组 合并后的新数组
bash 复制代码
// 示例1:join() 数组转字符串
var arr1 = [1,2,3,4];
var str1 = arr1.join('-'); // 用连字符分隔
var str2 = arr1.join(); // 无参数,默认逗号
console.log(str1); // '1-2-3-4'
console.log(str2); // '1,2,3,4'
console.log(arr1); // [1,2,3,4](原数组不变)

// 示例2:concat() 合并数组
var arr2 = [5,6];
var arr3 = arr1.concat(arr2, 'a', true); // 可合并数组和单个元素
console.log(arr3); // [1,2,3,4,5,6,'a',true]
console.log(arr1); // [1,2,3,4](原数组不变)

(7)数组方法:截取与替换

slice用于截取数组片段,splice可实现截取、替换、添加元素(功能灵活,常用),注意两者对原数组的影响差异。

方法 功能 是否修改原数组 返回值
slice(开始索引, 结束索引) 截取数组从开始索引到结束索引(含头不含尾),索引可负数(表示从末尾算) 截取到的新数组
splice(开始索引, 删除个数, 新增元素...) 从开始索引删除指定个数元素,可选在该位置添加新元素 被删除元素组成的数组(无删除则返回空数组)
bash 复制代码
// 示例1:slice() 截取数组
var arr = [1,2,3,4,5];
var newArr1 = arr.slice(1, 3); // 从索引1开始,到索引3结束(不含3)
var newArr2 = arr.slice(-2); // 负数索引,从末尾第2个元素开始截取到最后
console.log(newArr1); // [2,3]
console.log(newArr2); // [4,5]
console.log(arr); // [1,2,3,4,5](原数组不变)

// 示例2:splice() 删除元素
var delArr1 = arr.splice(2, 2); // 从索引2开始,删除2个元素
console.log(arr); // [1,2,5](原数组被修改)
console.log(delArr1); // [3,4](返回被删除元素)

// 示例3:splice() 替换元素(删除+添加)
var delArr2 = arr.splice(1, 1, 'a', 'b'); // 从索引1删1个元素,添加'a'和'b'
console.log(arr); // [1,'a','b',3,4,5]
console.log(delArr2); // [2](返回被删除元素)

// 示例4:splice() 仅添加元素(删除个数设为0)
var delArr3 = arr.splice(3, 0, 6, 7); // 从索引3开始,删0个,添加6和7
console.log(arr); // [1,2,3,'a','b',6,7,4,5]
console.log(delArr3); // [](无删除,返回空数组)

(8)数组方法:排序与反转

用于数组元素的排序和顺序反转,均会直接修改原数组。

方法 功能 是否修改原数组 返回值
reverse() 反转数组元素的顺序 反转后的原数组
sort() 默认按字符串Unicode编码排序,可传入比较函数自定义排序规则 排序后的原数组
bash 复制代码
// 示例1:reverse() 反转数组
var arr1 = [1,2,3,4];
arr1.reverse();
console.log(arr1); // [4,3,2,1](原数组修改)

// 示例2:sort() 默认排序(字符串规则,存在问题)
var arr2 = [10, 2, 23];
arr2.sort();
console.log(arr2); // [10,2,23](按首字符Unicode排序,不符合数字排序预期)

// 示例3:sort() 传入比较函数(数字升序/降序)
// 升序:a - b < 0 → a排在b前面
arr2.sort(function(a, b) {
  return a - b;
});
console.log(arr2); // [2,10,23]

// 降序:b - a < 0 → b排在a前面
arr2.sort(function(a, b) {
  return b - a;
});
console.log(arr2); // [23,10,2]

// ES6箭头函数简写(升序)
arr2.sort((a, b) => a - b);

(9)数组方法:查找元素

用于查找数组中指定元素的索引或判断是否存在,不同方法适配不同场景。

方法 功能 是否修改原数组 返回值
indexOf(元素, 起始索引) 从左到右查找元素,起始索引可选(默认0) 找到返回对应索引,未找到返回-1 严格匹配(===),区分数据类型
lastIndexOf(元素) 从右到左查找元素 找到返回对应索引,未找到返回-1 严格匹配(===),区分数据类型
bash 复制代码
var arr = [1,2,3,2,4];
// 示例1:indexOf() 从左查找
var idx1 = arr.indexOf(2); // 默认从索引0开始
var idx2 = arr.indexOf(2, 2); // 从索引2开始查找
console.log(idx1); // 1
console.log(idx2); // 3

// 示例2:lastIndexOf() 从右查找
var idx3 = arr.lastIndexOf(2);
console.log(idx3); // 3(最右侧匹配元素的索引)

// 示例3:未找到元素返回-1
var idx4 = arr.indexOf(5);
console.log(idx4); // -1

// 示例4:严格匹配(区分类型)
var arr2 = [1, '1', 2];
console.log(arr2.indexOf(1)); // 0(匹配数字1)
console.log(arr2.indexOf('1')); // 1(匹配字符串'1')

补充 :ES6新增includes()方法,用于判断数组是否包含指定元素,返回布尔值(arr.includes(2) → true),同样严格匹配,使用更直观。

4.4 数据格式:JSON(轻量级数据交换格式)

JSON(JavaScript Object Notation)不是内置对象,而是通用数据格式,常用于前后端数据传输,语法和JS对象类似,但有严格规范。

(1)JSON语法规则

  • 键名必须用双引号包裹(JS对象可省略引号)
  • 值只能是字符串、数字、布尔、null、数组、JSON对象(不能是函数、undefined)
  • 不能有多余逗号(末尾不能加逗号)
bash 复制代码
// 合法JSON格式
{
  "name": "张三",
  "age": 20,
  "isStudent": true,
  "hobbies": ["篮球", "编程"]
}

// 非法JSON格式(键名无引号、值含函数)
{
  name: "张三",
  sayHello: function() {}
}

(2)JSON与JS对象的转换

通过JSON全局对象的两个方法实现转换,是前后端交互的核心操作。

方法 功能 示例
JSON.parse(jsonStr) JSON字符串 → JS对象 JSON.parse('{"name":"张三"}')
JSON.stringify(obj) JS对象 → JSON字符串 JSON.stringify({name:"张三"})
bash 复制代码
// 1. JSON字符串转JS对象
var jsonStr = '{"name":"张三","age":20}';
var obj = JSON.parse(jsonStr);
console.log(obj.name); // 张三(可正常访问属性)

// 深拷贝技巧
let copy = JSON.parse(JSON.stringify(person));

// 2. JS对象转JSON字符串
var user = { name: "李四", age: 22 };
var jsonStr2 = JSON.stringify(user);
console.log(jsonStr2); // "{"name":"李四","age":22}"(字符串格式)

五、BOM对象:操作浏览器的接口

**BOM(Browser Object Model,浏览器对象模型)**是JS操作浏览器的接口,无官方标准,核心对象是window(全局对象,所有BOM属性/方法都挂载在window上,可省略window前缀)。

5.1 核心BOM对象

(1)window对象(全局对象)

window是JS全局作用域的顶层对象,所有全局变量、函数、内置对象都属于window。

bash 复制代码
// 全局变量本质是window的属性
var msg = "Hello";
console.log(window.msg); // Hello

// 全局函数本质是window的方法
function sayHi() {
  console.log("Hi");
}
window.sayHi(); // Hi

常用弹窗方法

方法 功能 特点
alert(内容) 弹出警告框 无返回值,阻断页面执行
confirm(提示语) 弹出确认框(确定/取消) 返回布尔值(确定true/取消false)
prompt(提示语,默认值) 弹出输入框 返回用户输入内容(取消返回null)

(2)location对象(地址栏信息)

用于获取或修改浏览器地址栏信息,实现页面跳转等功能。

属性/方法 功能
location.href 获取当前页面完整URL,修改可实现跳转
location.reload() 刷新当前页面(参数true强制刷新,忽略缓存)
location.assign(url) 跳转到指定URL,可后退返回原页面
bash 复制代码
// 1. 获取当前URL
console.log(location.href); // https://www.example.com

// 2. 跳转页面(两种方式)
location.href = "https://www.baidu.com"; // 直接修改href跳转
location.assign("https://www.baidu.com"); // 调用assign方法跳转

// 3. 刷新页面
location.reload(); // 普通刷新
location.reload(true); // 强制刷新

(3)history对象(浏览历史)

用于操作浏览器的浏览历史记录,仅能操作当前窗口的历史。

方法 功能
history.back() 后退到上一页(等同于浏览器后退按钮)
history.forward() 前进到下一页(等同于浏览器前进按钮)
history.go(n) 跳转到指定历史记录(n为正数前进n页,负数后退n页,0刷新)

(4)navigator对象(浏览器信息)

用于获取浏览器的基本信息,常用于浏览器兼容性判断。

bash 复制代码
// 获取浏览器用户代理信息(包含浏览器版本、内核等)
console.log(navigator.userAgent); //'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36'

// 判断是否为移动设备(简单判断)
var isMobile = /Mobile|Android/.test(navigator.userAgent);
console.log(isMobile ? "移动设备" : "桌面设备");

六、DOM对象:操作网页元素的接口

DOM(Document Object Model,文档对象模型)是JS操作网页元素的接口,将HTML文档视为一个树形结构(DOM树),每个HTML标签都是一个DOM节点(元素节点、文本节点、属性节点)。

6.1 DOM树核心概念

  • 文档节点(document):整个HTML文档的根节点,所有DOM操作都从document开始
  • 元素节点(Element) :HTML标签(如<div>、<p>、<button>
  • 文本节点(Text):标签内的文本内容
  • 属性节点(Attribute) :标签的属性(如class、id、src

6.2 核心操作:获取DOM元素

先获取到DOM元素,才能对其进行修改、删除等操作,常用获取方法如下:

方法 功能 返回值
getElementById(id值) 通过id属性获取元素(id唯一) 单个元素节点(未找到返回null)
getElementsByClassName(类名) 通过class属性获取元素 HTMLCollection集合(类数组)
getElementsByTagName(标签名) 通过标签名获取元素 HTMLCollection集合(类数组)
querySelector(选择器) 通过CSS选择器获取元素(ES6新增) 第一个匹配的元素节点
querySelectorAll(选择器) 通过CSS选择器获取所有匹配元素 NodeList集合(类数组)
bash 复制代码
// 1. 通过id获取(最常用,高效)
var box = document.getElementById("box");

// 2. 通过class获取(返回集合,需遍历)
var items = document.getElementsByClassName("item");
console.log(items[0]); // 取第一个元素

// 3. 通过CSS选择器获取(灵活,推荐ES6使用)
var btn = document.querySelector("#btn"); // id选择器
var lis = document.querySelectorAll("ul li"); // 后代选择器

6.3 核心操作:修改DOM元素

(1)修改元素内容

属性/方法 功能 特点
innerHTML 设置/获取元素内的HTML内容 支持HTML标签解析
innerText 设置/获取元素内的文本内容 忽略HTML标签,只保留文本
bash 复制代码
var box = document.getElementById("box");
// 1. 修改内容(支持HTML标签)
box.innerHTML = "<h3>修改后的标题</h3>";
// 2. 修改纯文本
box.innerText = "修改后的纯文本";
// 3. 获取内容
console.log(box.innerHTML);

(2)修改元素样式

通过style属性修改元素行内样式,属性名采用驼峰命名法(如backgroundColor替代background-color)。

bash 复制代码
var box = document.getElementById("box");
// 1. 修改单个样式
box.style.width = "200px";
box.style.backgroundColor = "red";
box.style.fontSize = "18px";

// 2. 通过class修改样式(推荐,分离样式和脚本)
box.className = "active"; // 替换原有class
box.classList.add("new-class"); // 新增class
box.classList.remove("active"); // 移除class

(3)修改元素属性

直接通过元素节点的属性名修改,或使用setAttribute()/getAttribute()方法。

bash 复制代码
var img = document.querySelector("img");
// 1. 直接修改属性
img.src = "new-img.jpg";
img.alt = "新图片";

// 2. 用方法修改属性
img.setAttribute("title", "图片标题"); // 设置属性
console.log(img.getAttribute("src")); // 获取属性值
img.removeAttribute("alt"); // 移除属性

6.4 核心操作:添加/删除DOM元素

bash 复制代码
// 1. 创建新元素
var newDiv = document.createElement("div");
newDiv.innerText = "新创建的div";
newDiv.style.color = "blue";

// 2. 添加元素到页面(插入到body末尾)
document.body.appendChild(newDiv);

// 3. 插入到指定元素前面
var box = document.getElementById("box");
document.body.insertBefore(newDiv, box); // 把newDiv插入到box前面

// 4. 删除元素(需通过父元素删除)
document.body.removeChild(newDiv);

6.5 核心操作:DOM事件(元素交互)

事件是用户与网页的交互行为(如点击、鼠标移动、键盘输入),通过绑定事件处理器,可让元素响应交互。

(1)常用事件类型

  • onclick:点击事件
  • onmouseover:鼠标移入事件
  • onmouseout:鼠标移出事件
  • onkeyup:键盘松开事件
  • onload:页面加载完成事件

(2)事件绑定方式

bash 复制代码
var btn = document.getElementById("btn");

// 方式1:行内事件(不推荐,耦合度高)
// <button onclick="handleClick()">按钮</button>
function handleClick() {
  alert("按钮被点击了");
}

// 方式2:DOM0级事件(直接赋值)
btn.onclick = function() {
  console.log("DOM0级点击事件");
};

// 方式3:DOM2级事件(addEventListener,推荐,可绑定多个事件)
btn.addEventListener("click", function() {
  console.log("DOM2级点击事件1");
});
btn.addEventListener("click", function() {
  console.log("DOM2级点击事件2");
});

// 移除DOM2级事件(需用命名函数)
function handleBtnClick() {
  console.log("可移除的事件");
}
btn.addEventListener("click", handleBtnClick);
btn.removeEventListener("click", handleBtnClick);

注意:事件处理函数中的this,指向绑定事件的DOM元素,可通过this操作当前元素。

第七章:实用技巧与最佳实践

7.1 调试技巧

bash 复制代码
// 1. 使用debugger语句
function calculate() {
debugger; // 执行到这里会暂停
let result = 10 * 5;
return result;
}

// 2. 条件断点
console.log("调试信息");
// 在开发者工具中右键行号添加条件断点

// 3. 性能分析
console.time("操作耗时");
// 执行一些代码
console.timeEnd("操作耗时"); // 显示执行时间

7.2 代码组织

bash 复制代码
// 立即执行函数(IIFE)
(function() {
	// 私有变量,不会污染全局
	let privateVar = "私有";
	console.log(privateVar);
})();

// 模块模式
let myModule = (function() {
  let privateVar = "私有";

	function privateMethod() {
	  console.log(privateVar);
	}

return {
	publicMethod: function() {
	   privateMethod();
	}
};
})();

myModule.publicMethod();

7.3 错误处理

bash 复制代码
// 1. try...catch
try {
  let result = riskyOperation();
} catch (error) {
  console.error("出错啦:", error);
	// 优雅降级
	showFallbackUI();
} finally {
	console.log("无论如何都会执行");
}

// 2. 自定义错误
function validateAge(age) {
	if (age < 0) {
		throw new Error("年龄不能为负数");
	}
	if (age > 150) {
		throw new Error("年龄不现实");
	}
}

// 3. Promise错误处理
fetch("https://api.example.com/data")
.then(response => response.json())
.catch(error => console.error("请求失败", error));

常用资源推荐

相关推荐
半夏知半秋1 天前
rust学习-循环
开发语言·笔记·后端·学习·rust
维C泡泡1 天前
STL(初识string)
开发语言·c++
郝学胜-神的一滴1 天前
Linux线程使用注意事项:骈文技术指南
linux·服务器·开发语言·数据结构·c++·程序人生
叫我:松哥1 天前
基于 Flask 的音乐推荐与可视化分析系统,包含用户、创作者、管理员三种角色,集成 ECharts 进行数据可视化,采用混合推荐算法
开发语言·python·信息可视化·flask·echarts·pandas·推荐算法
此剑之势丶愈斩愈烈1 天前
mybatis-plus乐观锁
开发语言·python·mybatis
CC.GG1 天前
【Qt】常用控件----容器类控件(QGroupBox、QTabWidget )以及布局管理器
开发语言·qt
缘如风1 天前
Qt Creator 断点调试断点停不住
开发语言·qt
ghie90901 天前
MATLAB中实现基于高斯混合模型(GMM)的心电信号两级分类
开发语言·matlab·分类
勘察加熊人1 天前
python实现批量中英文文件翻译
开发语言·windows·python