JavaScript入门
基本语法
- 变量声明
1 | // ES5 |
- 数据类型
1 | // 基本类型 |
- 增强for循环
1 | // for...of (ES6) |
- 错误处理
1 | try { |
- 解构赋值
1 | // 数组解构 |
- 展开运算符
1 | let arr1 = [1, 2]; |
- 导出模块
1 | // math.js |
- 导入模块
1 | // app.js |
函数
- 函数声明时,函数名前加上
function
关键字即可
1 | function print(s) { |
箭头函数
- 不绑定自己的
this
、arguments
、super
或new.target
。
1 | const sum = (a,b) => { |
- 简化
- 单参数:可省略括号
- 单行表达式:可省略大括号和
return
(隐式返回)
函数提升
- 指的是在代码执行前,JavaScript 引擎会将函数声明和变量声明"提升"到它们所在作用域的顶部。
- 函数声明会完全被提升,包括函数名和函数体
- 函数表达式不会被提升,只有变量声明会被提升,函数赋值部分不会
- 箭头函数的实现永远不会被提升
回调函数
- 回调函数(Callback Function)是 JavaScript 中一种重要的编程模式,它是作为参数传递给另一个函数,并在特定条件满足或操作完成后被调用的函数。
- 实例
1 | function greet(name, callback) { |
数组
- 创建数组
1 | // 字面量方式 |
- 常见方法
方法 | 描述 | 是否修改原数组 | 返回值 | 示例 |
---|---|---|---|---|
push() |
末尾添加一个或多个元素 | ✅ | 新长度 | arr.push('a') |
pop() |
删除并返回最后一个元素 | ✅ | 删除的元素 | arr.pop() |
unshift() |
开头添加一个或多个元素 | ✅ | 新长度 | arr.unshift('a') |
shift() |
删除并返回第一个元素 | ✅ | 删除的元素 | arr.shift() |
splice() |
添加/删除任意位置元素 | ✅ | 被删除的元素数组 | arr.splice(1,0,'x') |
concat() |
合并多个数组 | ❌ | 新数组 | arr1.concat(arr2) |
slice() |
截取子数组 | ❌ | 新数组 | arr.slice(1,3) |
fill() |
填充数组元素 | ✅ | 修改后的数组 | arr.fill(0) |
- 遍历与转换方法
方法 | 描述 | 是否修改原数组 | 返回值 | 示例 |
---|---|---|---|---|
forEach() |
对每个元素执行函数 | ❌ | undefined | arr.forEach(x=>console.log(x)) |
map() |
映射为新数组 | ❌ | 新数组 | arr.map(x=>x*2) |
filter() |
过滤符合条件的元素 | ❌ | 新数组 | arr.filter(x=>x>5) |
reduce() |
累计为单个值 | ❌ | 累计结果 | arr.reduce((a,b)=>a+b,0) |
reduceRight() |
从右向左累计 | ❌ | 累计结果 | arr.reduceRight((a,b)=>a+b) |
flat() |
扁平化嵌套数组 | ❌ | 新数组 | arr.flat(2) |
flatMap() |
先映射后扁平化 | ❌ | 新数组 | arr.flatMap(x=>[x,x*2]) |
join() |
数组转字符串 | ❌ | 字符串 | arr.join(',') |
toString() |
数组转字符串 | ❌ | 字符串 | arr.toString() |
- 搜索与排序方法
方法 | 描述 | 是否修改原数组 | 返回值 | 示例 |
---|---|---|---|---|
indexOf() |
查找元素首次出现位置 | ❌ | 索引/-1 | arr.indexOf('a') |
lastIndexOf() |
查找元素最后出现位置 | ❌ | 索引/-1 | arr.lastIndexOf('a') |
includes() |
检查是否包含某元素 | ❌ | boolean | arr.includes('a') |
find() |
查找第一个符合条件的元素 | ❌ | 元素/undefined | arr.find(x=>x>5) |
findIndex() |
查找第一个符合条件的索引 | ❌ | 索引/-1 | arr.findIndex(x=>x>5) |
sort() |
排序数组 | ✅ | 排序后的数组 | arr.sort((a,b)=>a-b) |
reverse() |
反转数组顺序 | ✅ | 反转后的数组 | arr.reverse() |
对象
- 对象是键值对的集合.
- 引用类型:对象是引用类型,赋值和传参传递的是引用
- 动态属性:可以随时添加或删除属性
- 原型继承:每个对象都有一个原型链
- 属性描述符:每个属性都有配置特性(可写、可枚举、可配置)
1 | var user = { |
Math对象
Math.abs()
绝对值Math.min()
最小值,Math,max()
最大值Math.round()
四舍五入,Math.ceil()
向上取整,Math.floor()
向下取整Math.random()
返回0~1的伪随机数
1 | //返回min~max的随机数 |
- 幂和开方
1 | Math.pow(2, 3) // 8 - 2的3次方(ES6中也可用 2 ** 3) |
Date对象
- Date 对象是 JavaScript 中用于处理日期和时间的内置对象,它可以表示从 1970 年 1 月 1 日 UTC(Unix 纪元)以来的毫秒数。
创建新对象
1 | const now = new Date(); // 创建当前时间的Date对象 |
获取时间戳
- 时间戳:从固定参考时间点(通常是1970年1月1日00:00:00 UTC)开始计算的经过的秒数或毫秒数。
1 | const timestamp = Date.now(); // 当前时间戳(毫秒) |
获取具体时间
1 | const date = new Date(); |
设置时间
1 | const date = new Date(); |
日期格式化
1 | const date = new Date(); |
- 自定义格式化
1 | function formatDate(date) { |
DOM
- DOM (Document Object Model) 是 JavaScript 操作网页内容的接口,它将 HTML 和 XML 文档表示为树形结构,使程序能够动态访问和更新文档的内容、结构和样式。
- 含义
- 文档对象模型:将 HTML/XML 文档表示为节点树
- 编程接口:提供操作文档的方法和属性
- 跨平台标准:由 W3C 标准化,各浏览器实现
节点
- 在 DOM (Document Object Model) 中,节点(Node) 是构成文档树的基本单位,代表了文档结构中的每一个组成部分。DOM 将整个文档抽象为一个由各种类型节点组成的树形结构。
节点类型
- 文档节点 (Document Node)
- 文档类型节点 (DocumentType Node)
- 属性节点 (Attribute Node)
- 元素节点 (Element Node)
- 文本节点 (Text Node)
- 注释节点 (Comment Node)
- nodeType属性,不同节点对应不同nodeType。
document.nodeType - 9
节点树
1 | document (根节点) |
- 节点关系
1 | parentNode // 父节点 |
Document方法
- 获取元素
1 | // 通过ID获取 |
节点操作
- 创建节点
1 |
|
- 添加节点
1 | // 末尾添加子节点 |
- 删除/替换
1 | // 删除子节点 |
属性操作
1 | // 获取/设置属性 |
类名操作
1 | // classList API |
事件处理
HTML事件
- HTML 事件是发生在 HTML 元素上的"事情",可以是浏览器行为(如页面加载完成)或用户行为(如点击按钮)。
- 可以直接在 HTML 元素中指定事件处理程序
1 | <button onclick="demo()">点击我</button> |
DOM0级事件
- DOM0级事件是早期的事件处理方式,也被称为"传统事件模型"。
- 同一事件只能绑定一个处理函数。
1 | //先获取元素,在设置事件 |
DOM2级事件
- DOM2级事件是更现代的事件处理模型,提供了更强大的功能。
- 可以为同一事件添加多个处理函数
1 | const btn = document.getElementById('myButton'); |
事件冒泡
- 事件冒泡是指当一个DOM元素上的事件被触发时,该事件会从目标元素开始,向上逐级传播到DOM树的最顶层节点(通常是document对象)的过程。
事件传播的阶段
- 捕获阶段(Capture Phase):
- 从window对象向下传播到目标元素的父级
- 使用
addEventListener
的第三个参数true
可以监听此阶段 - 从最外层祖先元素向内传播
- 目标阶段(Target Phase):
- 事件到达目标元素本身
- 无论是否设置捕获都会触发
- 如果事件不可冒泡,传播到此结束
- 冒泡阶段(Bubble Phase):
- 从目标元素向上传播回window对象
- 大多数事件默认在此阶段触发处理程序
事件代理
- 事件代理是一种利用事件冒泡机制的高效事件处理模式,它通过将事件监听器设置在父元素而非子元素上来管理多个子元素的事件。
- 事件冒泡机制:当子元素触发事件时,事件会向上冒泡到父元素
- 目标元素识别:通过
event.target
可以识别实际触发事件的子元素 - 统一处理:在父元素上设置一个监听器处理所有子元素的事件
事件对象
-
事件对象是事件发生时浏览器自动创建的,包含了与该事件相关的所有信息。当事件触发时,浏览器会将这个事件对象作为参数传递给事件处理函数。
-
基本属性
1 | event.type // 事件类型(如"click"、"mouseover"等) |
- 常见方法
1 | event.preventDefault() // 阻止元素的默认行为 |
常见事件
鼠标事件
1 | // 单击事件 |
键盘事件
1 | // 键按下 |
表单事件
1 |
|
窗口事件
1 | // 整个页面(包括资源)加载完成 |
定时器
-
用于延迟执行代码或定期重复执行代码。
-
注意
setTimeout
中的this
指向全局环境。 -
setTimeout
: 延迟执行(执行一次)
1 | // 格式(接受两个参数,推迟执行的函数,推迟执行的时间,返回定时器编号) |
setInterval
:间隔执行(无限执行)
1 | let count = 0; |
防抖
- 防抖是一种控制函数执行频率的技术,它可以确保一个函数在一定时间间隔内只执行一次,特别适合处理高频触发的事件。
- 防抖含义
- 当事件被频繁触发时
- 只有在事件停止触发后的指定时间间隔内不再有新触发
- 才会执行一次事件处理函数
1 | function debounce(f,delay) { |
工作原理
- 首次调用:
timer
为null
,跳过clearTimeout
- 设置一个新的定时器,计划在
delay
毫秒后执行f
- 在
delay
时间内再次调用:timer
不为null
(有定时器存在)- 清除之前的定时器(取消之前计划的执行)
- 设置一个新的定时器,重新开始计时
- 停止调用
delay
时间后:- 没有新的调用来清除定时器
- 定时器到期,执行原始函数
f
节流
- 节流(Throttle)是一种控制函数执行频率的技术,它可以确保函数在一定时间间隔内最多执行一次,特别适合处理高频触发的事件。
- 节流含义
- 当事件被频繁触发时
- 无论触发多频繁,函数都会按照固定的时间间隔执行
- 确保执行频率不会超过设定的限制
1 | function throttle(f,delay) { |
工作原理
- 首次调用:
valid
为true
,允许执行- 设置
valid
为false
阻止后续调用 - 设置定时器,在
delay
毫秒后执行函数并重置valid
- 在
delay
时间内再次调用:valid
为false
,直接返回不执行- 保持节流状态
- 定时器到期后:
- 执行原始函数
f
- 重置
valid
为true
- 允许下一次调用
- 执行原始函数