文章目录
- 一、JavaScript简介
-
- [1.1 JavaScript简介](#1.1 JavaScript简介)
- [1.2 JavaScript引入方式](#1.2 JavaScript引入方式)
- [1.3 输入与输出语法](#1.3 输入与输出语法)
- 二、变量与数据类型
-
- [2.1 变量](#2.1 变量)
- [2.2 数据类型](#2.2 数据类型)
- [2.3 数据类型转化](#2.3 数据类型转化)
- [2.4 深/浅拷贝](#2.4 深/浅拷贝)
- 三、运算符与语句
-
- [3.1 运算符](#3.1 运算符)
- [3.2 Math内置对象](#3.2 Math内置对象)
- [3.3 分支语句(if和switch)](#3.3 分支语句(if和switch))
- [3.4 循环语句(while与for)](#3.4 循环语句(while与for))
- [3.5 异常处理](#3.5 异常处理)
- 四、数组与对象
-
- [4.1 数组](#4.1 数组)
- [4.2 对象(类似字典)](#4.2 对象(类似字典))
- 五、函数与定时器
-
- [5.1 函数](#5.1 函数)
- [5.2 构造函数与继承](#5.2 构造函数与继承)
- [5.3 定时器](#5.3 定时器)
- 六、日期对象
- 七、正则表达式
- 八、闭包
一、JavaScript简介
1.1 JavaScript简介
JavaScript是一种轻量级、解释型或即时编译的编程语言,主要用于为网页添加交互功能。作为Web开发的三大核心技术之一(与HTML和CSS并列),它允许动态更新内容、控制多媒体、处理用户输入等
相关文档:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript
核心特点
跨平台 :支持所有现代浏览器(Chrome、Firefox、Safari等)和服务器环境(如Node.js)。
动态类型 :变量类型在运行时确定,无需显式声明。
事件驱动 :通过监听用户操作(如点击、滚动)触发代码执行。
异步编程:支持Promise、async/await等非阻塞操作模式。
应用场景
前端开发 :操作DOM、表单验证、动画效果。
后端开发 :通过Node.js构建服务器应用。
移动开发 :使用框架如React Native开发跨平台应用。
游戏开发:结合HTML5 Canvas或库如Phaser。
1.2 JavaScript引入方式
| 方式 | 介绍 |
|---|---|
| 内部JavaScript | 直接写在html文件里,用script标签包住(script标签写在</body>上面) |
| 外部JavaScript | 代码写在以.js结尾的文件里,然后引入到html文件中 |
| 行内JavaScript | 代码写在标签内部,如代码中的button里面,在vue中会常用这种模式 |
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<!-- 页面主体内容 行内JavaScript -->
<button onclick="alert('弹出警示框')">点击弹出警示框</button>
<!-- 内部JavaScript -->
<script>
alert("弹出警示框")
</script>
<!-- 外部JavaScript -->
<script src="./JavaScript.js"></script>
</body>
</html>
JavaScript.js文件
javascript
alert("弹出警示框")
1.3 输入与输出语法
输入和输出可以理解为人和计算机的交互,用户通过键盘、鼠标等向计算机输入信息,计算机处理后再展示结果给用户
输出语法
| 函数 | 作用 |
|---|---|
alert("警示对话框") |
页面弹出警示对话框 |
console.log("控制台打印") |
控制台输出语句,一般用于调试时定位问题 |
document.write("body内容") |
向body内输出write里面的内容 |
javascript
// 弹出警示对话框
alert("警示对话框")
// 在控制台打印
console.log("控制台打印")
// 直接展示在界面上
document.write("Hello Word")
输入语法
| 函数 | 作用 |
|---|---|
prompt("请输入内容:") |
显示一个对话框,对话框中包含一条文字信息,用来提示用户输入文字 |
javascript
// 输入语句 可以通过变量接收输入的信息
let uname = prompt("请输入姓名:")
JavaScript代码执行顺序
按HTML文档流顺序执行JavaScript(从上往下)
alert和prompt会跳过页面渲染先被执行
二、变量与数据类型
2.1 变量
JavaScript 中主要有三种变量声明方式:
var、let和const。
var :传统声明方式,存在变量提升问题,作用域为函数级(被 let 取代)。
let : ES6 新增的块级作用域声明,用于声明允许重新赋值变量 (常用)
const :ES6 新增的块级作用域声明,用于声明不可变的常量
对于变量声明,首先var先排除,老派写法,问题很多,可以淘汰掉建议const优先,尽量使用const,原因是:const语义化更好;很多变量我们声明的时候就知道他不会被更改了;实际开发中也是,比如react框架,基本const
变量命名规则
变量名必须以字母、下划线 _ 或美元符号 $ 开头。
后续字符可以是字母、数字、下划线或美元符号。
JavaScript 区分大小写,myVar 和 myvar 是不同的变量。
避免使用 JavaScript 保留字(如 function、class 等)作为变量名
作用域
var 声明的变量存在函数作用域,会提升到函数顶部。
let 和 const 具有块级作用域({} 内有效),不存在变量提升。
javascript
if (true) {
var x = 10; // 函数作用域
let y = 20; // 块级作用域
}
console.log(x); // 10
console.log(y); // ReferenceError
最佳实践
优先使用 const,除非需要重新赋值。
避免使用 var,以减少作用域混淆。
使用有意义的变量名,如 userAge 而非 ua。
对于常量,使用全大写命名(如 MAX_SIZE)。
2.2 数据类型
JavaScript 是动态类型语言,变量无需预先指定类型。常见数据类型包括:
原始类型:number数字型、string字符串型、boolean布尔型、null空类型、undefined未定义型、symbol(ES6)
引用类型:object对象(包括数组 Array、函数 Function 等)
JavaScript是弱数据类型,变量到底属于那种类型,只有赋值之后,我们才能确认
检测数据类型
输出可以判断数据是什么数据类型,可以
typeof x格式或者typeof(x)格式
javascript
let age = 25
let name = "Alice"
console.log(typeof age) // typeof 变量名
console.log(typeof(name)) // typeof(变量名)
// 判断数据是否为数字
console.log(isNaN(2))
instanceof:可以用来判断某变量是否为某数据类型
javascript
const a = [1, 2]
// a 是否为 Array类型
const.log(a instanceof Array)
数字类型(number)
数字型可以是整数、小数、正数、负数,数字类型可以进行算术运算,比如加 + 、减 - 、乘 * 、除 / 、取余 % 等
注:计算错误的时候会返回 NaN,比如字符串与数字运行。NaN与任何运算都是NaN,NaN不等于NaN
javascript
let num1 = 10, num2 = 20
console.log(num1 + num2) // 30
console.log("a" + num1) // NaN
console.log(NaN === NaN) // false
// 保留小数位数
console.log(num1.toFixed(2))
// 判断数据是否为数字
console.log(isNaN(2))
字符串类型(string)
通过单引号(")、双引号("")或反引号(`)包裹的数据都叫字符串
模板字符串 :必须使用反引号(``),内容拼接变量时,用${}包住变量
javascript
let str1 = 'hello'
let str2 = 'world'
// 字符串拼接
console.log(str1 + ' ' + str2)
// 模板字符串拼接
console.log(`${str1} world`)
// 字符串拆分
console.log('hello world'.split(' '))
// 字符串是否包含某字符串
console.log('hello world'.includes('world'))
console.log('hello world'.indexOf('world')) // 返回子字符串首次出现的索引
console.log('hello world'.search('world')) // 返回子字符串首次出现的索引 支持正则表达式
console.log(/hello/i.test("Hello, world!")); // true 正则匹配 i 表示不区分大小写
| 属性 | 含义 |
|---|---|
| length | 长度 |
| split | 拆分 |
| substring | 字符串截取 |
| startsWith | 是否以某字符开头 |
| endsWith | 是否以某字符结尾 |
| includes | 是否包含某字符串 |
| toUpperCase | 字母转大写 |
| toLowerCase | 字母转小写 |
| indexOf | 是否包含某字符 |
| replace | 替换,支持正则 |
| match | 查找,支持正则 |
布尔类型(boolean)
表示肯定或否定时在计算机中对应的是布尔类型数据。
它有两个固定的值true和false,表示肯定的数据用true(真),表示否定的数据用false(假)
javascript
let isFlag = true
console.log(isFlag) // true
console.log(3 < 4) // true
显示转换布尔类型:''、0、undefined、null、false、NaN 转换为布尔值后都是false,其余则为true
javascript
console.log(Boolean(1)) // true 显示转换为布尔类型
未定义类型(undefined)
未定义是比较特殊的类型,只有一个值undefined
只声明变量,不赋值的情况下,变量的默认值为undefined,一般很少[直接]为某个变量赋值为undefined
javascript
let num // 声明未赋值
console.log(num) // undefined
空类型(null)
JavaScript中的null仅仅是一个代表"无"、"空"或"值未知"的特殊值
javascript
let obj = null
console.log(obj) // null
| 类型 | 区别 |
|---|---|
| undefined | 表示没有赋值 |
| null | 表示赋值了,但是内容为空 |
javascript
console.log(undefined + 1) // NaN
console.log(null + 1) // 1
2.3 数据类型转化
JavaScript是弱数据类型:JavaScript也不知道变量到底属于那种数据类型,只有赋值了才清楚。
使用表单、prompt获取过来的数据默认是字符串类型的,此时就不能直接简单的进行加法运算。比如下面例子
javascript
let num1 = prompt("请输入一个数:")
console.log(typeof num1) // string
console.log('100' + '200') // 100200
此时需要转换变量的数据类型。就是把一种数据类型的变量转换成我们需要的数据类型。
隐式转换
某些运算符被执行时,系统内部自动将数据类型进行转换,这种转换称为隐式转换。
规则1、+号两边只要有一个是字符串,都会把另外一个转成字符串
2、除了+以外的算术运算符比如-*/等都会把数据转成数字类型
缺点1、转换类型不明确,靠经验才能总结
小技巧1、+号作为正号解析可以转换成数字型
2、任何数据和字符串相加结果都是字符串
javascript
console.log('1' + 1) // 11 后面的隐式转换为字符串
console.log(1 - '1') // 0 后面的隐式转换为数字型
显示转换
编写程序时过度依靠系统内部的隐式转换是不严禁的,因为隐式转换规律并不清晰,大多是靠经验总结的规律。为了避免因隐式转换带来的问题,通常根逻辑需要对数据进行显示转换。
概念 :自己写代码告诉系统该转成什么类型
转换为数字型 :1、
Number(数据):转换为数字类型2、
parseInt(数据):只保留整数3、
parseFloat(数据):可以保留小数
javascript
let str = '123'
console.log(typeof str) // '123' string
console.log(Number(str)) //123 数字型
console.log(Number('hello')) // NaN
2.4 深/浅拷贝
深拷贝和浅拷贝是JavaScript中复制对象的两种方式。浅拷贝只复制对象的引用,而深拷贝会递归复制对象的所有属性,生成一个全新的对象
浅拷贝
浅拷贝只复制第一层属性,深层属性仍然是引用。修改拷贝对象的深层属性会影响原对象
javascript
const a = {
'uname': 'Tony',
'family': {
"body": "abc"
}
}
// 浅拷贝
// family、uname都会跟随 a 变化
const b = a
// family会跟随 a 变化、uname 不会跟随 a 变化
const c = { ...a }
// family会跟随 a 变化、uname 不会跟随 a 变化
const d = {}
Object.assign(d, a)
a['uname'] = "Jack"
a['family']['body'] = "Jack"
深拷贝
深拷贝是完全独立的副本,修改任何属性都不会影响原对象
html
<script src="./loadsh.main.js"></script>
<script>
const a = {
'uname': 'Tony',
'family': {
"body": "abc"
}
}
// 深拷贝 family、uname 都不会跟随 a 变化
// 先转字符串 再转回来
const e = Json.parse(Json.stringify(a))
// 利用第三方库 _.cloneDeep需要先导入
// lodashjs.com
const f = _.cloneDeep(a)
a['uname'] = "Jack"
a['family']['body'] = "Jack"
</script>
三、运算符与语句
3.1 运算符
赋值运算符
对变量进行赋值的运算符
常用的赋值运算符 = ,还有 += ,-=, *=, /=, %=
javascript
let num = 1
num += 1
一元运算符
众多的JavaScript的运算符可以根据所需表达式的个数,分为一元运算符、二元运算符、三元运算符
一元运算符:一个数能够使用一元运算符做自增运算
javascript
let num = 1
// 一元运算符:后置自增
num++
// 一元运算符:前置自增
++num
// 两者单独写一行自增没区别,
// 如果使用console.log(i++)或者console.log(++i)则会有区别
// 两者可以理解为 先用后加 和 先加后用
比较运算符
比较两个数据大小、是否相等,比较结果为boolean类型,即true或false
尽量不对比小数,会有小数精度问题
| 运算符 | 含义 |
|---|---|
| > | 大于 |
| < | 小于 |
| >= | 大于等于 |
| <= | 小于等于 |
| == | 值是否相等 |
| === | 类型和值都相等 |
| !== | 是否不全等 |
javascript
console.log(2 == '2') // true
console.log(2 === '2') // false
console.log(NaN === NaN) // false NaN不等于任何值,包括自己
console.log('a' < 'b') // true 字符串比较是ASCII码比较
console.log('abc' < 'bcd') // true 先比第一位,相同则比第二位...
逻辑运算符
逻辑运算符用来解决多重条件判断
| 符号 | 含义 |
|---|---|
| && | 逻辑与 |
| || | 逻辑或 |
| ! | 逻辑非 |
javascript
console.log(3 < 5 && 5 < 10)
运算符优先级
| 优先级 | 运算符 | 顺序 |
|---|---|---|
| 1 | 小括号 | () |
| 2 | 一元运算符 | ++ -- ! |
| 3 | 算术运算符 | 先 * / % 后 + - |
| 4 | 关系运算符 | > >= < <= |
| 5 | 相等运算符 | == != === !== |
| 6 | 逻辑运算符 | 先 && 后 || |
| 7 | 赋值运算符 | = |
| 8 | 逗号运算符 | , |
3.2 Math内置对象
Math对象是JavaScript提供的一个"数学"对象,提供了一系列做数学运算的方法
Math对象相关使用参考:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Math
| Math对象 | 作用 |
|---|---|
| random | 生成0-1之间的随机数(包含0 不包含1) |
| ceil | 向上取整 |
| floor | 向下取整 |
| max | 找最大数 |
| min | 找最小数 |
| pow | 幂运算 |
| abs | 绝对值 |
javascript
console.log(Math.PI)
console.log(Math.random() * 10) // 取[0,10)之间的数
console.log(Math.ceil(1.1)) // 2
console.log(min([1, 2, 3])
// 取6-10范围的数,可通过取0-4之间的数的基础上加6
Math.random() * 4 + 6
// 取整数,可以结合取整函数使用
Math.floor(Math.random() * 4)
3.3 分支语句(if和switch)
分支语句包含 if分支语句、三元运算符、switch语句
if分支语句
if分支语句有三种:单分支、双分支、多分支
单分支
javascript
if (true) {
console.log(1)
}
双分支
javascript
if (false) {
console.log(1)
} else {
console.log(2)
}
多分支
javascript
if (false) {
console.log(1)
} else if (true) {
console.log(2)
} else {
console.log(3)
}
三元运算符
其实是比if双分支更简单的写法,?与:配合使用
javascript
// 条件 ? 复合条件执行 : 不符合条件执行
let a = 1 > 2 ? 3 : 4
1 < 3 ? console.log(1) : console.log(2)
switch语句
利用switch执行满足条件的语句。switch case语句一般用于等值判断,不适合于区间判断。switch case一般需要配合break关键字使用 没有break会造成case穿透。
找到跟小括号里数据全等的case值,并执行里面对应的代码若没有全等=== 的则执行default里的代码
javascript
let num = 2
switch (num) {
case 1:
console.log(1)
break // 退出switch
case 2:
console.log(2)
break // 退出switch
default:
console.log(0)
break // 退出switch
}
3.4 循环语句(while与for)
while循环
循环:重复执行一些操作
while循环:在满足条件期间,重复执行某些代码,循环的本质就是以某个变量为起始值,然后不断产生变化量,慢慢靠近终止条件的过程
javascript
let i = 0
while (i < 10) {
console.log(i)
i++
}
for循环
javascript
for (let i = 0; i < 10; i++) {
console.log(i)
}
// 循环数组
let arr = ['a', 'b', 'c']
for (let i = 0; i < arr.length; i++) {
console.log(arr[i])
}
// 遍历索引
for (index in arr) {
console.log(arr[index])
}
// 遍历值
for (value of arr) {
console.log(value)
}
循环相关关键字
continue:结束本次循环,继续下一次循环
javascript
let i = 0
while (i<10) {
if (i %2 == 0) {
i++
continue
}
console.log(i)
i++
}
break:退出当前层循环
javascript
let i = 0
while (true) {
console.log(i)
i++
if (i >= 10) {
break
}
}
3.5 异常处理
异常处理是 JavaScript 中用于捕获和处理运行时错误的机制。当代码执行过程中出现错误时,异常处理可以防止程序崩溃,并提供错误恢复或日志记录的机会
try - catch
try-catch 是 JavaScript 中最常用的异常处理结构。try 块包含可能抛出错误的代码,catch 块用于捕获并处理错误
javascript
function add(x, y) {
const result = 0
try {
result = x + y
} catch (error) {
console.log(error.message)
return result
} finally { // 不管是否正常 一定执行
return result
}
// 出错不执行
console.log('hello')
}
console.log(add())
throw
通过 throw 可以主动抛出错误。可以抛出字符串、数字、对象或 Error 对象,JavaScript提供了多种内置错误类型:
Error:通用错误类型。
SyntaxError:语法错误。
TypeError:类型错误(如调用非函数)。
ReferenceError:引用错误(如访问未定义变量)。
RangeError:数值超出范围
javascript
function add(x, y) {
if(!x, !y){
// throw 'error'
throw new Error("error")
}
return x+y
}
console.log(add())
四、数组与对象
4.1 数组
数组(Array)是一种可以按顺序保存数据的数据类型。如果有多个数据可以用数组保存起来,然后放到一个变量中,管理非常方便,数组赋值时,需要考虑深浅拷贝的问题
| 数组函数 | 含义 |
|---|---|
| slice | 拷贝序号2~5的位置 |
| concat | 合并数组 |
| join | 将数组中的元素用指定的连接符号连接成一个字符串 |
| length | 数组长度 |
| sort | 就地排序 |
| reverse | 就地反转 |
| findIndex | 找到第一个符合要求的值 |
| find | 返回数组中满足提供的测试函数的第一个元素的值 |
| every | 是否都能通过指定函数的测试 |
| some | 是否至少有一个元素通过了由提供的函数实现的测试 |
| from | 伪数组转真数组 |
数组声明
javascript
// 使用 new Array 构造函数声明 数组
let arr = new Array([1, 2, 'a', 'b'])
// 字面量声明数组
let a = [0, 1, 2, 3, 4, 5, 6];
数组插入
| 数组函数 | 含义 |
|---|---|
| push | 添加元素 |
| unshift | 头部添加元素 |
| splice | 删除或插入数据 |
javascript
// 末尾插入 'a'
a.push('a') // a.push('b', 'c') 末尾插入 'b' 'c'
// 开头插入 'd'
a.unshift('d')
// 从索引 3 的位置插入 a b 元素
a.splice(2, 0, 'a', 'b');
数组删除
| 数组函数 | 含义 |
|---|---|
| pop | 默认删除末尾元素 |
| shift | 头部删除元素 |
| splice | 删除或插入数据 |
javascript
// 从索引 3 的位置开始删除 2 个元素
a.splice(3, 2)
// 删除最后一个元素
a.pop()
// 删除第一个元素
a.shift()
// 清空数组
a.length = 0
a = []
// 通过filter删除指定元素并获取新数组(获取大于10的数据)
const b = a.filter(item => item > 10);
数组查找
javascript
// 数组中是否存在 a 元素
console.log(a.includes('a'))
console.log(a.indexOf('a')) // 返回元素在数组中的索引
数组遍历
for遍历
javascript
let arr = new Array([1, 2, 'a', 'b'])
for (let i = 0; i < arr.length; i++) {
console.log(arr[i])
}
// 遍历索引
for (const index in arr) {
console.log(arr[index])
}
// 遍历值
for (const value of arr) {
console.log(value)
}
数组遍历(map)
map 是 JavaScript 数组的一个高阶函数,用于对数组中的每个元素执行指定的操作,并返回一个新数组,而不会改变原数组
javascript
const arr = ['1', '2', '3']
const newArr = arr.map(function (ele, index) {
return ele + 'a'
})
console.log(newArr) // ['1a', '2a', '3a']
数组遍历(forEach)
forEach()方法用于调用数组的每个元素,并将元素传递给回调函数
数组.forEach(function (当前元素, 当前索引) { }
javascript
const a = [1, 2, 3, 4]
a.forEach(function(item, index) { // item必传 index可选
console.log(item, index)
})
map重点在于有返回值,forEach没有返回值
filter过滤
filter()方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素
javascript
const arr = [1, 2, 3, 4]
// 过滤大于2的值
const newArr = arr.filter(function(item, index) {
return item > 2 // item + 5 每个元素加5
})
const newArr = arr.filter(function(item => item > 2) // 等同于上面函数 省略了index参数
console.log(newArr)
reduce
累计器,返回累计处理的结果,经常用于求和等
arr.reduce(function(上一次值, 当前值){}, 初始值)
javascript
const arr = [1, 2, 3]
// 无初始值
console.log(arr.reduce(function(prev, current){
return prev + current
})) // 1 + 2 + 3 = 6
// 有初始值
console.log(arr.reduce(function(prev, current){
return prev + current
}, 10)) // 10 + 1 + 2 + 3 = 16
join拼接
join()方法用于把数组中的所有元素转换一个字符串
javascript
const arr = ['1', '2', '3']
console.log(arr.join(', ')) // 1, 2, 3
展开运算符
展开运算符 可以展开数组,不会修改原数组,可以用于求最大最小值、合并数组等
javascript
const arr1 = [1, 2, 3]
const arr2 = [4, 5, 6]
// 最大值
console.log(Math.max(...arr1)) // Math.max(1, 2, 3)
// 合并数组
console.log([...arr1 , ...arr2])
数组解构
将数组的单元值快速批量赋值给一系列变量的简洁语法。
javascript
let [a, b, c] = [1, 2, 3];
// 互换两个值,上一句,末尾需加分号
[a, b] = [b, a]
// e包含多个值
const [q, w, ...e] = [1, 2, 3, 4, 5, ,6]
// 默认参数
const [a, b = 0, c = 0] = [1, 2]
4.2 对象(类似字典)
对象是JavaScript里的一种数据类型,可以理解为是一种无序的数据集合,注意数组是有序的数据集合
用来描述某个事物,例如描述一个人:人有姓名、年龄、性别等信息、还有吃饭睡觉打代码等功能
如果用多个变量保存则比较散,用对象比较统一
注:对象的使用需要注意深浅拷贝问题
javascript
// 属性声明
let people = {
username: 'Tony',
age: 18
}
// 属性访问
console.log(people.username) // 或者 people['username']
// 属性修改
people.age = 20
// 属性增加
people.gender = '男'
// 属性删除
delete people.gender
对象中的方法:声明对象,并添加了若干方法后,可以使用.调用对象中函数,我称之为方法调用。也可以添加形参和实参
javascript
// 属性声明
let people = {
username: 'Tony',
say: function() {
console.log(1)
}
}
// 方法调用
peoople.say()
对象遍历
javascript
// 属性声明
let people = {
username: 'Tony',
age: 18
}
// 遍历
for (let key in people) { // key 为username、age
console.log(key, people[key])
}
获取key、value值
javascript
console.log(Object.keys(people)) // ['username', 'age']
console.log(Object.values(people)) // ['Tony', 18]
Object.assign(a, b)是 JavaScript 中用于合并对象的方法,将对象 b 的可枚举属性复制到对象 a 中。如果 a 和 b 有相同的属性,b 的属性值会覆盖 a 的属性值
javascript
Object.assign(a, b)
构造函数创建对象
构造函数是一种特殊的函数,主要用来初始化对象,能够用来创建对象
要求:命名以大写字母开头;有new操作符来操作
javascript
// 构造函数
function Func(name, age) {
this.uname = name
this.age = age
}
// 创建对象
const Prople = new Func('Tony', 18)
console.log(Prople)
对象解构
javascript
// 变量名 与 对象属性名 保持相同
const {uname, age} = { uname: 'Tony', age: 18 }
// 冒号改名 什么值: 赋值给谁
const {uname: username, age} = { uname: 'Tony', age: 18 }
javascript
// 利用解构 只用对象中的 data
function func({data: myData}) {
console.log(myData) // hello
}
func({data: "hello", msg: "world"})
五、函数与定时器
5.1 函数
函数是被设计为执行特定任务的代码块。函数可以把具有相同或相似逻辑的代码"包裹"起来,通过函数调用执行这些被"包裹"的代码逻辑,这么做的优势是有利于精简代码方便复用。
| 已封装函数 | 说明 |
|---|---|
| confirm() | 确认对话框 |
| alert() | 警告框 |
| prompt() | 输入框 |
| console.log() | 输出框 |
函数名命名规范
和变量命名基本一致
尽量小驼峰式命名法
前缀应该为动词
命名建议:常用动词约定
javascript
// 函数声明
function print() {
console.log(1)
}
// 函数调用
print()
函数传参
javascript
function add(unm1, num2, num3=0) { // num1 num2 num3 为形参
return unm1 + num2 + num3
}
console.log(add(1, 2, 3)) // 1 2 3 为实参
console.log(add(1, 2)) // 第3个参数默认为0
console.log(add(1)) // 第二个没传,则为Nan,最后结果为NaN (NaN与任何值运算都为NaN)
动态参数 :
arguments是函数内部内置的伪数组变量,它包含了调用函数时传入的所有实参,动态参数是伪数组
javascript
function sum() {
let s = 0
for( let i = 0; i < arguments.length; i++){
s += arguments[i]
}
console.log(s)
}
sum(1, 2)
sum(1, 2, 3)
剩余参数(推荐):剩余参数允许我们将一个不定数量的参数表示为一个数组,剩余参数是真数组
javascript
function sum(...arr) { // 也可以(a, b, ...arr)
let s = 0
for( let i = 0; i < arr.length; i++){
s += arr[i]
}
console.log(s)
}
sum(1, 2)
sum(1, 2, 3)
匿名函数
没有名字的函数,无法直接使用。
使用方式 :1、函数表达式:将匿名函数赋值给一个变量,并且通过变量名称进行调用我们将这个称为函数表达式
javascript
let add = function (unm1, num2) {
return unm1 + num2
}
console.log(add(1, 2))
2、立即执行函数:避免全局变量之间的污染
javascript
// 方式一
(function (num1, num2) {
console.log(num1 + num2)
})(1, 2);
// 方式二
(function (num1, num2) {
console.log(num1 + num2)
}(1, 2));
// 注:后面一定要加分号
箭头函数
箭头函数的目的是更简短的函数写法并且不绑定this,箭头函数的语法比函数表达式更简洁。箭头函数更适用于那些本来需要匿名函数的地方
javascript
const add = (a, b) => {
console.log(a + b)
}
add(1, 2)
只有一个参数可以省略括号
javascript
const add = a => {
console.log(a)
}
add(1, 2)
代码只有一行可以省略大括号,也可以省略return
javascript
const add = (a, b) => a + b
console.log(add(1, 2))
// 返回一个对象
const fn = uname => ({uname: uname})
console.log(fn('Tony'))
箭头函数没有arguments动态参数,但是有剩余参数
javascript
const add = (...arr) => {
let s = 0
for( let i = 0; i < arr.length; i++){
s += arr[i]
}
console.log(s)
}
add(1, 2, 3)
箭头函数的this是上一层作用域的this 指向
javascript
const func = () => {
console.log(this) // window
}
func()
对象方法箭头函数 this为window
javascript
const obj = {
say: () => {
console.log(this) // window
},
func: function() {
console.log(this) // obj
const coutnt = () => {
console.log(this) // 指向上一层 obj
}
count()
}
}
obj.say()
obj.func()
5.2 构造函数与继承
构造函数
封装是面向对象思想中比较重要的一部分,js面向对象可以通过构造函数实现的封装。
同样的将变量和函数组合到了一起并能通过this实现数据的共享,所不同的是借助构造函数创建出来的实例对象之间是彼此不影响的
构造函数体现了面向对象的封装特性
javascript
// 构造函数
function Func(name, age) {
this.uname = name
this.age = age
this.funct = function () {
console.log(1)
}
}
// 创建对象
const a = new Func('Tony', 18)
const b = new Func('F', 16)
console.log(a.funct === b.funct) // false
存储复杂类型数据时,会存在浪费空间问题,比如创建两个对象,两个对象中都有一样的函数(funct)
对于这种情况,可以通过原型方法解决
原型
目标:能够利用原型对象实现方法共享
构造函数通过原型分配的函数是所有对象所共享的。
JavaScript规定,每一个构造函数都有一个prototype属性,指向另一个对象,所以我们也称为原型对象这个对象可以挂载函数,对象实例化不会多次创建原型上函数,节约内存
我们可以把那些不变的方法,直接定义在prototype对象上,这样所有对象的实例就可以共享这些方法。
构造函数和原型对象中的this都指向 实例化的对象
上面代码改写后如下,可以节省内存
javascript
// 构造函数
function Func(name, age) {
this.uname = name
this.age = age
}
// prototype 中有个 constructor 属性指向父亲 Func
Func.prototype.funct = function () {
console.log(1)
}
// 创建对象
const a = new Func('Tony', 18)
const b = new Func('F', 16)
// 对象中有 __proto__ 属性指向prototype
console.log(a.funct === b.funct) // true
console.log(a.__proto__ === a.prototype) // true
继承是面向对象编程的另一个特征,通过继承进一步提升代码封装的程度,JavaScript中大多是借助原型对象实现继承的特性。
javascript
// 出来的对象 结构一样,但是对象不一样构造函数new
function Afunc() {
this.name = 'Tony'
this.age = 12
}
function Bfunc() {
}
// 通过原型继承 Afunc
Bfunc().prototype = new Afunc()
// 指回原来的构造函数
Bfunc().prototype.constructor = Brunc
const.log(Bfunc instanceof Afunc)
5.3 定时器
setInterval 和 setTimeout 是 JavaScript 中用于延迟执行代码或周期性执行代码的两个核心函数。它们均属于 Web API,由浏览器或 Node.js 环境提供,用于管理异步任务
setInterval(重复多次)
setInterval 用于每隔固定时间重复执行回调函数,直到被清除
开启定时器 :setInterval(callback, interval, [arg1], [arg2], ...)
callback:每次间隔时间结束后执行的函数。
interval:间隔时间(毫秒)。
arg1, arg2, ...:可选参数,传递给回调函数
关闭计时器 :clearInterval(变量名)
javascript
let i = 0
function print() {
i++
console.log(i)
}
// 开启定时器 一秒执行一次print函数
let n = setInterval(print, 1000)
// 关闭计时器
clearInterval(n)
setTimeout(单次)
setTimeout 用于在指定的延迟时间后执行一次回调函数。
定时设置函数 :setTimeout(callback, delay, [arg1], [arg2], ...)callback:延迟结束后执行的函数。
delay:延迟时间(毫秒),默认为 0。
arg1, arg2, ...:可选参数,传递给回调函数
取消执行函数 :clearTimeout(变量名)
javascript
// 定时器设置
let timer = setTimeout(function() {
console.log(1)
}, 1000)
// 定时器清除
clearTimeout(timer)
六、日期对象
JavaScript 的 Date 对象用于处理日期和时间,支持从系统获取当前时间或创建自定义日期
实例化
javascript
// 获得当前时间
console.log(new Date())
// 获得指定时间
console.log(new Date('2026-1-1'))
console.log(new Date('2026-1-1 08:30:00'))
时间对象方法
目标 :能够使用日期对象中的方法写出常见日期
使用场景:因为日期对象返回的数据我们不能直接使用,所以需要转换为实际开发中常用的格式
| 方法 | 作用 | 说明 |
|---|---|---|
| getFullYear() | 获得年份 | 获取四位年份 |
| getMonth() | 获得月份 | 取值为0~11 |
| getDate() | 获取月份中的每一天 | 不同月份取值也不相同 |
| getDay() | 获取星期 | 取值为0~6 |
| getHours() | 获取小时 | 取值为0~23 |
| getMinutes() | 获取分钟 | 取值为0~59 |
| getSeconds() | 获取秒 | 取值为0~59 |
javascript
const date = new Date()
console.log(date.getFullYear())
console.log(date.getMonth() + 1)
javascript
const div = document.querySelector('div')
const date = new Date()
// 展示到div中
div.innerHTML = date.toLocaleDateString()
时间戳
如果计算倒计时效果,前面方法无法直接计算,需要借助于时间戳完成
将来的时间戳 - 现在的时间戳 = 剩余时间毫秒数
获取时间戳方式:
getTime():
+new Date():无需实例化
Date.now():无需实例化,但是只能得到当前的时间戳,而前面两种可以返回指定时间的时间戳
javascript
const date = new Date()
console.log(date.getTime())
console.log(+new Date())
console.log(Date.now())
// 指定时间戳
console.log(+new Date('2026-3-1 04:00:00')
七、正则表达式
正则表达式是一种用于匹配和处理文本的强大工具。它通过定义一种模式(pattern),可以快速搜索、替换或提取字符串中的特定内容
正则相关介绍参考链接:https://blog.csdn.net/weixin_46287157/article/details/116429118?spm=1011.2415.3001.5331
对于正则表达式这里不做过多的介绍,简单介绍了正则表达式在JavaScript中如何使用
javascript
// 是否匹配 匹配返回true 否则false
console.log(/\d+/.test('hello 23 world'))
// 执行搜索匹配
console.log(/\d+/.exec('hello 23 world'))
// i 表示不区分大小写
console.log(/\d+/i.exec('hello 23 world'))
// g 匹配所有满足条件的结果
console.log(/l/g.exec('hello 23 world'))
// 正则替换
console.log('abc 123 def'.replace(/\d+/, ','))
// 忽略大小写且全局替换
console.log('abc 123 def'.replace(/\d+/ig, ','))
八、闭包
闭包 :一个函数对周围状态的引用捆绑在一起,内层函数中访问到其外层函数的作用域,简单理解就是闭包= 内层函数+外层函数的变量
用途:当声明私有变量,允许外部调用访问,但不允许外部修改时,考虑闭包
javascript
function func () {
let i = 0 // 不能被外部修改
function add () {
i++
console.log(i)
}
return add
}
let fn = func();
fn() // 1
fn() // 2