一、javascript基础
1. javascript简介
⑴ javascript的起源
⑵ javascript 简史
⑶ javascript发展的时间线
⑷ javascript的实现
⑸ js第一个代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js基础</title>
<!-- js代码写在script标签中在head里 -->
<script type="text/javascript">
/*
*控制浏览器弹出一个警告
*/
alert("弹出一条指令框");
/*
*让计算机在页面中输出一个内容
*document.write()可以向bodyz中输出一个内容
*/
document.write("向文档(body)写一个内容");
/*
* 向控制台输出一个内容
* console.log()的作用是向控制台输出一个内容
*/
console.log("向控制台输出一个内容");
</script>
</head>
<body>
</body>
</html>
2. js编写的位置
⑴ 可以将js代码编写到onclick属性里面
<!-- 1. 可以将js代码编写到onclick属性里面
当我们点击按钮的时候,js代码才会执行 -->
<button onclick="alert('你点了我一下~')">点击一下</button>
⑵ 可以将js代码编写到超链接的href属性中
<!-- 2. 可以将js代码编写到超链接的href属性中,这样当我们点击超链接的时候,会执行js代码 -->
<a href="javascript:alert('你又点我我一下~')">你再点我一下</a>
<a href="javascript:;">你也点我一下</a>
⑶ js代码写在script标签中在head里
<!-- 3. js代码写在script标签中在head里 -->
<script type="text/javascript">
alert("我是内部的js代码");
</script>
⑷ 可以将js代码写在外部js文件中,让后通过script标签引入
alert("我是外部的js代码");
<!-- 4. 可以将js代码写在外部js文件中,让后通过script标签引入
写在外部的js文件可以引入到不同的页面中去,也可以利用浏览器的缓存机制
这是推荐使用的方法
注意:
script标签一旦引用了外部的文件,就不能在编写代码了,即使编写了代码,浏览器也会忽略
如果需要在script中编写代码,则需要再创建一个script标签用于编写内部的js代码 -->
<script type="text/javascript" src="js/script.js"> </script>
<!-- 3. js代码写在script标签中在head里 -->
<script type="text/javascript">
alert("我是内部的js代码");
</script>
3. javascript 基本语法
⑴ 注释
-
多行注释
<script type="text/javascript"> /** * 多行注释 * - 注释中的内容会被解释器忽略 * - 可以通过注释来对代码解释说明 * - 也可以通过注释来去掉不想执行的代码 */ </script>
-
单行注释
<script type="text/javascript"> //单行注释 </script>
⑵ js严格区分大小写
⑶ 在js中多个空格和换行会被忽略,可以利用这个特点来对代码进行格式化
⑷ js 中每条语句都应该以分号结尾,js中具有自动添加分号的机制,所以如果不写分号解释器会自动添加
4. 字面量和变量
变量的使用:
-
先声明后赋值
<script type="text/javascript"> //声明变量 用let或者var声明变量 let a; //变量赋值 a = 10; console.log(a); </script>
-
声明和赋值同时进行
<script type="text/javascript"> //声明和赋值同时进行 let a = 10; console.log(a); </script>
5. 变量和内存结构
<script type="text/javascript">
let a = '哈哈';
let b = '哈哈';
</script>
6. 常量
除了变量外,在JS中还可以使用const
关键字来声明常量,区别于变量,常量只能在初始化时对其赋值,一旦赋值则无法修改。
<script type="text/javascript">
const PI = 3.1415926
console.log(PI);
</script>
注意:
7. 标识符
关键字列表:
保留字列表:
8. 数据类型
⑴ 数值和大整数
数值就是数字,在JavaScript中数字有两种普通的数值和大整数。
1) 数值
2) 大整数
3) 类型检查 typeof
typeof
用来检查不同值的类型,它会根据不同的值返回不同的结果
<script type="text/javascript">
let a = 10;
let b = 100n;
console.log(typeof a);
console.log(typeof b);
</script>
⑵ 字符串
1)字符串介绍
JavaScript中字符串需要使用引号引起来,单引号和双引号都是可以的,没有本质区别。使用typeof
运算符检查一个字符串时会返回"string"。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js讲解</title>
<script type="text/javascript">
let c = '字符串';
console.log(typeof c);
</script>
</head>
<body>
</body>
</html>
2) javascript 中的转义字符
3)模板字符串
模板字符串可以用来表示一些比较长的字符串(跨行),且可以直接向字符串中嵌入变量,使用 ` 表示模板字符串,在模板字符串中使用 ${变量}来嵌入变量:
let str = `锄禾日当午
汗滴禾下土
谁知盘中餐
粒粒皆辛苦
`
let name = "孙悟空"
let str = `大家好,我是${name}`
例如:
⑶ 其他数据类型
1) boolean 布尔值
2) 空值 null
3) undefined
未定义
4) 符号symbol
注意: 上边所有的原始值都是不可变的类型,值一旦创建就无法修改!
⑷ 类型转换
1)其他类型转换成字符串
① 调用toString()
方法,将其他类型转换成字符串
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js讲解</title>
<script type="text/javascript">
let a = 10;
console.log(typeof a ,a);
a = a.toString();
console.log(typeof a,a);
</script>
</head>
<body>
</body>
</html>
注意:由于
null
和undefined
没有toString()方法,所以对它两调用toString()方法会报错
② 调用String()函数,将其他类型转换成字符串
对应拥有toString()
方法的值调用String()函数时,实际上就是在调用toString()方法。
对于null,则直接转换成"null"
对于undefined,则直接转换成"undefined"
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js讲解</title>
<script type="text/javascript">
let a = 10;
console.log(typeof a ,a);
a = String(a);
console.log(typeof a,a);
let b = null;
console.log(typeof b,b);
b = String(b);
console.log(typeof b,b);
let c = undefined;
console.log(typeof c,c);
c = String(c);
console.log(typeof c,c);
</script>
</head>
<body>
</body>
</html>
2)其他类型转换成数字
① 使用Number()
函数来将其他类型
转换成数值
转换情况:
- 字符串转换成数字:
如果字符串是一个合法的数字,则会自动转换成对应数值的数字类型
如果不是合法的数字,则转换成NaN
如果字符串是空串或者纯空格的字符串,则转换为0- 布尔值:
true转换成1,false转换成0- null
null转换成0- undefined
undefined转换为NaN
②使用parseInt()
函数来将字符串
转换成一个整数
parseInt()
将一个字符串转换成一个整数,解析时,会自左向右读取一个字符串,直到读取到字符串中所有有效的整数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js讲解</title>
<script type="text/javascript">
let a = '23.222';
a = parseInt(a);
</script>
</head>
<body>
</body>
</html>
可以用parseInt()来对一个数字进行取整
③ 使用parseFloat()
函数来将字符串
转换成一个浮点小数
parseFloat()
将一个字符串转换成一个小数,解析时,会自左向右读取一个字符串,直到读取到字符串中所有有效的浮点小数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js讲解</title>
<script type="text/javascript">
let b = '33.231';
b = parseFloat(b);
console.log(typeof b,b);
</script>
</head>
<body>
</body>
</html>
3)其他类型转换成布尔值
使用Boolean()
函数来将其他类型转换成布尔类型
4) 类型转换总结
-
转换为字符串
显式转换
String()
隐式转换
+""
-
转换为数值
显式转换
Number()
隐式转换
+
-
转换为布尔值
显式转换
Boolean()
隐式转换
!!
8. 运算符
运算符用来对一个或多个值进行运算并返回运算结果。比如,+
就是一个运算符,用来求两个数的和。let a = 1 + 1
,变量的a的值是2。
⑴ 算数运算符
//示例:
1 + 1 // 2
true + false //1
1 + "1" // "11"
10 % 3 // 1
2 ** 3 // 8
⑵ 赋值运算符
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js讲解</title>
<script type="text/javascript">
// let a = null;
let a = 10;
a ??= 100;
console.log(a);
</script>
</head>
<body>
</body>
</html>
⑶ 一元的+
和-
+
一元的加,正号–
一元的减,负号
⑷ 自增和自减
++
自增--
自减
注意:
自增会使变量立刻增加1,自增分为前自增++a
和后自增a++
,前自增会在自增后返回新值,后自增会在自增以后返回旧值,自减同理。
⑸ 逻辑运算符
-
!
逻辑非
-
&&
逻辑与
&&
逻辑与- 可以对两个值进行与运算
- 当
&&
左右都为true时,则返回true,否则返回false - 与运算是短路的与,如果第一个值为false,则不看第二个值
- 与运算是找false的,如果找到false则直接返回,没有false才会返true
- 对于非布尔值进行与运算,它会转换为布尔值然后运算但是最终会返回原值, 如果第一个值为false,则直接返回第一个值如果第一个值为true,则返回第二个值
-
||
逻辑或||
逻辑或- 可以对两个值进行或运算
- 当
||
左右有true时,则返回true,否则返回false - 或运算也是短路的或,如果第一个值为true,则不看第二个值
- 或运算是找true,如果找到true则直接返回,没有true才会返回false
- 对于非布尔值或运算,它会转换为布尔值然后运算,但是最终会返回原值,如果第一个值为true,则返回第一个如果第一个值为false,则返回第二个
注意:
逻辑与运算,在运算时会先检查第一个值是否是false,如果是false直接返回第一个,否则返回第二个。逻辑或正好相反,在运算时会先检查第一个值是否是true,如果是true则返回第一个,否则返回第二个。
false && true // false
0 && true // 0
true || false // true
1 || 2 // 1
⑹ 关系运算符
>
大于>=
大于等于<
小于<=
小于等于
- 关系运算符和后边的相等运算符都用来比较两个值的关系是否成立,关系成立时返回true,否则返回false
- 比较非数值时,会先转换为数值然后比较。如果两侧的值都是字符串,则会逐位比较字符串的Unicode编码
1 < 5 // true
1 < '5' // true
'11' < '5' // true
⑺ 相等运算符
-
==
相等运算符
相等运算符,用来比较两个值是否相等
使用相等运算符比较两个不同类型的值时,它会将其转换为相同的类型(通常转换为数值)然后再比较,类型转换后值相同也会返回true
null
和undefined
进行相等比较时会返回true,NaN
不和任何值相等,包括它自身
-
===
全等运算符
全等运算符,用来比较两个值是否全等。它不会进行自动的类型转换,如果两个值的类型不同直接返回false,null
和undefined
进行全等比较时会返回false
-
!=
不等运算符
用来检查两个值是否不等,会自动进行类型转换 -
!==
不全等运算符
用来检查两个值是否不等,不会自动进行类型转换
⑻ 条件运算符
condition ? exprIfTrue : exprIfFalse
三元运算符
执行顺序:
条件表达式 ?表达式1:表达式2
条件运算符在执行时,会先对条件表达式进行求值判断,如果结果为true,则执行表达式1如果结果为false,则执行表达式2
⑼ 运算符的优先级
9. 流程控制语句
⑴ 代码块
使用 {}
来创建代码块,代码块可以用来对代码进行分组。同一个代码中的代码,就是同一组代码,一个代码块中的代码要么都执行要么都不执行。
1) let与var的区别
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js讲解</title>
<script type="text/javascript">
{
var a = 'a';
let b = 'b';
}
console.log(a);
console.log(b);
</script>
</head>
<body>
</body>
</html>
⑵ if语句
1) 语法
if(条件表达式){
语句…
}
2) 执行流程
-
if语句在执行时会先对if后的条件表达式进行求值判断,如果结果为true,则执行,if后的语句如果为false则不执行
-
if语句只会控制紧随其后的那一行代码,如果希望可以控制多行代码,可以使用{}将语句扩起来最佳实践:即使if后只有1行代码,我们也应该写代码块,这样结构会更加的清晰
-
如果if后添加的表达式不是布尔值,则会转换成布尔值然后在进行运算
if(100){ alert('执行了if');//会执行 }
3) if-else语句
1) 语法
if(条件表达式){
语句…
}else if(条件表达式){
语句…
}
2) 执行流程
if-else执行时,先对条件表达式进行求值判断,如果结果为true 则执行if后的语句,如果结果为false 则执行else后的语句
⑶ switch语句
1) 语法
switch(){
case 表达式:
代码…
break;
case 表达式:
代码…
break;
case 表达式:
代码…
break;
default:
代码…
break;
}
2) 执行流程
switch语句在执行时,会依次将switch后的表达式和case后的表单式进行全等比较
如果比较结果为true,则自当前case处开始执行代码
如果比较结果为false,则继续比较其他case后的表达式,直到找到true为止
如果所有的比较都是false,则执行default后面的语句
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js讲解</title>
<script type="text/javascript">
let num = +prompt('请输入一个数字~');
switch(num){
case 1:
alert('壹');
break;
case 2:
alert('贰');
break;
case 3:
alert('叁');
break;
default:
alert('其他数字');
break;
}
</script>
</head>
<body>
</body>
</html>
总结:
switch语句和if语句的功能是重复的,switch能做的事if也能做,反之亦然,它们最大的不同在于,switch在多个全等列断时,结构比较清晰
10. 循环语句
通过循环语句可以使指定的代码反复执行
⑴ while语句
1) 语法
while(条件表达式){
语句…
}
通常情况下,编写一个循环体需要三个要素:
- 初始化表达式(初始化变量)
- 条件表达式(设置循环运行的条件)
- 更新表达式(修改初始化变量)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js讲解</title>
<script type="text/javascript">
//1.初始化表达式(初始化变量)
let i = 0;
//2.条件表达式(设置循环运行的条件)
while(i < 5){
console.log(i);
//更新表达式(修改初始化变量)
i++;
}
</script>
</head>
<body>
</body>
</html>
2) 执行流程
while语句在执行的时候,会先对条件表达式进行判断,如果结果为true,则执行循环体,执行完毕后继续判断。如果为true,则再次执行循环体,执行完毕后,继续判断,如此反复,直到条件表达式结果为false时,循环结束。
⑵ do-while 语句
1) 语法
do{
语句…
}while(条件表达式)
2) 执行顺序
do-while语句在执行中,会先执行do后面的循环体,执行完毕后,会对while后的条件表达式进行判断,如果为false,则循环体终止,如果为true,则继续执行循环体,以此类推。
do-while和while的区别
do-while是先执行后判断
while是先判断后执行
⑶ for循环
1) 语法
for(初始化表达式;条件表达式;更新表达式){
语句…
}
2)执行流程
1.执行初始化表达式,初始化变量
2.执行条件表达式,判断循环是否执行(true执行,false终止)
3.判断结果为true,则执行循环体
4.执行更新表达式,对初始化变量进行修改
5. 重复2,知道判断为false为止
⑷ break和continue
- break
1.break用来终止switch和循环体
2.break执行后当前的switch或循环会立刻终止 - continue
continue用来跳过当次循环体
11. 对象
对象是js中的一种复合类型的属性,它相当于一个容器,在对象中可以存储各种不同类型的数据。
⑴ 对象的基本操作
1) 创建对象
let obj = new Object();
可以简写成:let = Object();
2) 向对象中添加属性
对象中可以存储多个各种类型的数据,对象中存储的数据,我们称为属性
对象.属性名 = 属性值
3) 读取对象中的数据
对象.属性名
如果读取的是对象中没有的属性,不会报错,而是返回undefined
4) 修改属性值
对象.属性名 = 属性值
5) 删除属性
delete obj.name
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js讲解</title>
<script type="text/javascript">
let obj = Object();
obj.name = '张三';
obj.age = 19;
obj.sex = '男';
console.log(obj);
console.log(obj.age);
obj.age = 18;
console.log(obj.age);
delete obj.age;
console.log(obj.age);
</script>
</head>
<body>
</body>
</html>
⑵ 对象的属性
1)属性名
① 属性名的命名
-
通常属性名就是一个字符串,所以属性名可以是任何值,没有什么特殊要求,但是如果你的属性名太特殊了,不能直接使用,需要使用
[]
来设置,虽然如此,但是我们还是强烈建议属性名也按照标识符的规范命名<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>js讲解</title> <script type="text/javascript"> let obj = Object(); obj.name = "张三"; obj.if = "哈哈哈";//不建议 obj.let="嘻嘻";//不建议 obj["11233q@#$@!"] = "呵呵呵";//不建议 console.log(obj); console.log(obj["11233q@#$@!"]); </script> </head> <body> </body> </html>
-
也可以使用符号(Symbol)作为属性名来添加属性,获取这种属性时,务必使用Symbol。
使用Symbol添加的属性。通常是那些不希望被外界访问的属性。<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>js讲解</title> <script type="text/javascript"> let obj = Object(); obj.name = "张三"; let mySymbol = Symbol(); //使用Symbol作为属性名 obj[mySymbol] = "通过Symbol作为的属性名"; console.log(obj); console.log(obj[mySymbol]); </script> </head> <body> </body> </html>
② 通过.
和[]
添加属性的两种方式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js讲解</title>
<script type="text/javascript">
let obj = Object();
//通过.的方式添加属性
obj.name = "张三";
//通过[] 和 ""添加属性
obj["age"] = 18;
//通过变量和[]添加属性
let str = "address";
obj[str] = "中国";
//通过.添加属性
obj.str = "haha";//使用.添加属性的时候不能使用变量,这个等价于obj["str"] = "haha"
console.log(obj);
</script>
</head>
<body>
</body>
</html>
2) 属性值
对象的属性值可以是任意的数据类型,也可以是一个对象
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js讲解</title>
<script type="text/javascript">
let obj = Object();
obj.a = 123;
obj.b = "hello";
obj.c = true;
obj.d = 123n;
obj.e = Object();
obj.e.name = "张三";
obj.e.age = 13;
console.log(obj);
console.log(obj.e);
console.log(obj.e.name);
</script>
</head>
<body>
</body>
</html>
2) typeof
和 in
两个运算符
-
typeof
判断数据类型 -
in
判断 对象中是否存在某个属性,如果存在返回true,否则返回false。语法为:属性名
in
对象
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>js讲解</title> <script type="text/javascript"> let obj = Object(); obj.a = 123; obj.b = "hello"; obj.c = true; obj.d = 123n; obj.e = Object(); obj.e.name = "张三"; obj.e.age = 13; console.log(obj); console.log(obj.e); console.log(obj.e.name); console.log(typeof obj); console.log("name" in obj); console.log("name" in obj.e); </script> </head> <body> </body> </html>
⑶ 对象的字面量
可以使用{}
之间创建对象,使用{}
所创建的对象可以直接向对象中添加属性
语法
{
属性名:属性值,
[属性名]:属性值
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js讲解</title>
<script type="text/javascript">
let mySymbol = Symbol();
let obj = {
name:"张三",
age:18,
["gender"]:"男",
[mySymbol]:"符号类型",
hello:{
a:"哈哈哈"
}
};
console.log(obj);
</script>
</head>
<body>
</body>
</html>
⑷ 枚举对象中的属性for-in
枚举对象中的属性是指将对象中的属性全部获取
-
语法
for(let propName in 对象){
语句…
}for-in
的循环体会执行多次?有几个属性就会执行几次,每次执行时,都会将一个属性名赋值给我们所定义的变量注意:并不是所有的属性都可以枚举,比如使用符号添加的属性
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>js讲解</title> <script type="text/javascript"> let obj = { name:"张三", age:18, ["gender"]:"男", [Symbol()]:"符号类型",//符号类型的属性不能被枚举 hello:{ a:"哈哈哈" } }; for(let propName in obj){ console.log("属性名:"+propName,"属性值:"+obj[propName]); } </script> </head> <body> </body> </html>
⑸ 可变类型
1)原始值介绍
原始值都属于不可变类型,一旦创建就无法修改,在内存中不会创建重复的原始值。
let a = 10;
a = 12;
2)对象在内存中的情况
let obj = Object();
obj.name = "猪八戒";
obj.age = 18;
let obj = Object();
obj.name = "猪八戒";
obj.age = 18;
obj.name = "孙悟空";
对象属于可变类型,对象创建完成之后,可以任意添加、删除、修改对象中的属性。
注意:
① 当对两个对象进行相等或者全等比较时,比较的是对象的内存地址。
② 如果两个变量同时指向一个对象,通过一个变量修改对象时,对另一个对象也会产生影响。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js讲解</title>
<script type="text/javascript">
let obj1 = Object();
let obj2 = Object();
console.log(obj1 == obj2 );
let obj = {
name:"张三",
age:18
};
obj1 = obj;
obj2 = obj;
console.log(obj1);
console.log(obj2);
console.log(obj1 == obj2);
obj1.name = "李四";
console.log(obj1);
console.log(obj2);
</script>
</head>
<body>
</body>
</html>
⑹ 方法(method)
当一个对象的属性指向一个函数,那么我们就称这个函数是该对象的方法。调用函数就称为调用对象的方法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js讲解</title>
<script type="text/javascript">
let obj = {};
obj.name = "孙悟空";
//函数可以成为一个对象的属性
obj.sayHello = function(){
console.log("你好啊~");
}
console.log(obj);
obj.sayHello();
</script>
</head>
<body>
</body>
</html>
12. 函数(Function)
函数是一个对象,它具有其他对象的所有功能,函数中可以存储代码,且可以在需要时调用这些代码。
⑴ 语法
function 函数名(){
语句…
}
⑵ 函数简单的创建和调用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js讲解</title>
<script type="text/javascript">
function fn(){
console.log("函数内容");
}
fn();
console.log(typeof fn);
</script>
</head>
<body>
</body>
</html>
调用函数就是执行函数中存储的代码,使用typeof检查函数时会返回function。
⑶ 函数的创建方式
1) 函数声明
function 函数名([参数]){
语句…
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js讲解</title>
<script>
function fn(){
console.log("声明式函数定义~");
}
fn();
console.log(typeof fn);
</script>
</head>
<body>
</body>
</html>
2) 函数表达式
const fn = function([参数]){
语句…
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js讲解</title>
<script>
const fn = function(){
console.log("函数表达式定义~");
}
fn();
console.log(typeof fn);
</script>
</head>
<body>
</body>
</html>
3)箭头函数
const fn = ([参数])=>{
语句…
}
如果{}
只有一行,可以省略大括号。
const fn = ([参数])=>console.log(“箭头函数定义~”);
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js讲解</title>
<script>
const fn = ()=>{
console.log("箭头函数定义~");
}
fn();
console.log(typeof fn);
</script>
</head>
<body>
</body>
</html>
⑷ 函数参数
1) 形式参数
- 在定义函数时,可以在函数中指定数量不等的形式参数(形参)
- 在函数中定义形参,就相当于在函数内部声明了对应的变量但是没有赋值
2) 实际参数
- 在调用函数时,可以在函数()中传递数量不等的实参
- 实参会赋值给对应的形参
- 参数
○ 如果实参和形参数量相同,则对应的实参赋值给对应的形参
○ 如果实参多余形参,则多余的实参不会使用
○ 如果形参多余实参,则多余的形参为undefined
3) 参数类型
js中不会检查参数的类型,可以传递任何类型的值作为参数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js讲解</title>
<script>
const sum = function(a,b){
console.log(a + b);
}
sum(1,7);
</script>
</head>
<body>
</body>
</html>
4) 箭头函数的参数和参数默认值
① 箭头函数的参数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js讲解</title>
<script>
const fn = (a,b)=>{
console.log("a=",a);
console.log("a=",b);
}
fn(3,4);
</script>
</head>
<body>
</body>
</html>
② 当箭头函数的()
内只有一个参数的时候,()
可以省略
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js讲解</title>
<script>
const fn = a =>{
console.log("a=",a);
}
fn(8888888);
</script>
</head>
<body>
</body>
</html>
③ 定义函数的时候可以给参数指定默认值,默认值会在没有指定实参的时候生效
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js讲解</title>
<script>
function fn(a = 1,b = 2,c = 3){
console.log("a = ", a);
console.log("b = ",b);
console.log("c = ",c);
}
fn(9,4);
</script>
</head>
<body>
</body>
</html>
⑸ 使用对象作为参数
1) 修改对象的时候,如果有其他变量指向该对象,则所有指向该对象的变量都会受到影响
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js讲解</title>
<script>
function fn(a){
//修改对象的时候,如果有其他变量指向该对象,则所有指向该对象的变量都会受到影响
a.name = "猪八戒";
console.log(a);
}
//创建一个对象
let obj = {name:"孙悟空"};
//对象可以作为一个实参传递,传递实参时,传递的并不是变量本身,而是变量中存储的值
fn(obj);
console.log(obj);
</script>
</head>
<body>
</body>
</html>
2) 修改变量的时候,只会影响当前变量的值
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js讲解</title>
<script>
function fn(a){
//修改变量的时候,只会影响当前变量的值
a = {};
a.name = "猪八戒";
console.log(a);
}
//创建一个对象
let obj = {name:"孙悟空"};
//对象可以作为一个实参传递,传递实参时,传递的并不是变量本身,而是变量中存储的值
fn(obj);
console.log(obj);
</script>
</head>
<body>
</body>
</html>
3) 函数每次调用都会重新创建默认值
① 如果对象在()
内创建,则函数每次调用都会重新创建默认值
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js讲解</title>
<script>
//函数每次调用都会重新创建默认值
function fn(a = {name:"孙悟空"}){
console.log("a = ",a);
a.name = "猪八戒";
console.log("a = ",a);
}
fn();
fn();
</script>
</head>
<body>
</body>
</html>
② 如果对象在()
创建,则函数每次调用都访问同一个对象
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js讲解</title>
<script>
//函数每次调用都会重新创建默认值
let obj = {name:"孙悟空"};
function fn(a = obj){
console.log("a = ",a);
a.name = "猪八戒";
console.log("a = ",a);
}
fn();
fn();
</script>
</head>
<body>
</body>
</html>
⑹ 使用函数作为参数
在js中,函数也是一个对象(一等函数),别的对象能做的事情函数也能做。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js讲解</title>
<script type="text/javascript">
function fn(a){
console.log("a = ",a);
a();
}
let obj = {name:"孙悟空"};
function fn1(){
console.log("我是fn1函数");
}
fn(fn1);
fn(function(){
console.log("我是匿名函数~");
});
fn(()=>console.log("我是箭头函数~"));
</script>
</head>
<body>
</body>
</html>
⑺ 函数的返回值
在函数中,可以通过return
关键字来指定函数的返回值,返回值就是函数的执行结果,函数调用完毕返回值便会作为结果返回。
任何值都可以作为返回值使用(包括对象和函数之类)
如果return
后不跟任何值,则相当于返回undefined
,如果不写return
,那么函数的返回值依然是undefined
return
一执行函数立即结束
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js讲解</title>
<script type="text/javascript">
function fn(){
return 1+2;
}
let sum = fn();
console.log("sum = ",sum);
</script>
</head>
<body>
</body>
</html>
⑻ 箭头函数的返回值
箭头函数的返回值可以直接写在箭头后
如果直接在箭头后设置对象字面量为返回值时,对象字面量必须用()`括起案
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js讲解</title>
<script type="text/javascript">
const sum = function fn(a,b){
return a+b;
}
let result = sum(1,345);
console.log(result);
const addResult = (a,b)=> a + b;
let rs = addResult(345,543);
console.log(rs);
const objFun = function(){
return {name:"张三"};
}
let obj = objFun();
console.log(obj);
const objresult = ()=>({name:"李四"});
objrs = objresult();
console.log(objrs);
</script>
</head>
<body>
</body>
</html>
⑼ 作用域(scope)
作用域指的是一个变量的可见区域
1)全局作用域和局部作用域
作用城有两种:
全局作用域和局部作用域
① 全局作用域
- 全局作用域在网页运行时创建,在网页关闭时候销毁
- 所有直接编写到
<script>
标签中的代码都位于全局作用域中 - 全局作用域中的变量是全局变量,可以在任意位置访问
② 局部作用域
-
块作用域
○ 块作用域一种局部作用城
○ 块作用域在代码块执行时创建。代码块执行完毕它就销毁
○ 在块作用域中声明的变量是局部变量。只能在块内部访问,外部无法访问 -
函数作用域
○ 函数作用域也是一种局部作用域
○ 函数作用域在函数调用时产生,调用结来后销毁。
○ 函数每次调用都会产生一个全新的函数作用域
○ 在函数中定义的变量是局部变量。只能在函数内部访问,外无法访问。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js讲解</title>
<script type="text/javascript">
let a = "我是全局变量";
{
let b = "我是块中的局部变量";
{
console.log(b);
console.log(a);
}
}
function fn(){
let c = "我是函数中的局部变量";
}
// console.log(b); 无法访问
console.log(a);
console.log(c); //无法访问
</script>
</head>
<body>
</body>
</html>
2) 作用域链
当我们使用一个变量时,JS解释器会优先在当前作用域中寻找变量,
如果找到了则直接使用,如果没找到,则去上一层作用域中寻找,找到了则使用,如果没找到,则继续去上一层寻找,以此类推。如果一直到全局作用域都没找到,则报错xxxis not defined
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js讲解</title>
<script type="text/javascript">
let a = "全局变量a";
{
let a = "第一个代码块中的a";
{
let a = "第二个代码块中的a";
console.log(a);
}
}
let b = "全局变量b";
function fn(){
//let b = "第一个函数中的b";
function f1(){
//let b = "第二个函数中的b";
console.log(b);
}
f1();
}
fn();
</script>
</head>
<body>
</body>
</html>
⑽ window对象
1)window对象介绍
- 在浏览器中,浏览器为我们提供了一个window对象,可以直接访问
- window对象代表的是浏览器窗口,通过该对象可以对浏览器窗口进行各种操作,除此之外window对象还负责存储JS中的内置对象和浏览器的宿主对象
- window对象的属性可以通过window对象访问,也可以直接访问
- 函数就可以认为是window对象的方法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js讲解</title>
<script type="text/javascript">
console.log(window);
window.console.log(window);
window.a = "哈哈哈";
console.log(a);//向window对象中添加的属性会自动成为全局变量
</script>
</head>
<body>
</body>
</html>
2)var
声明变量的特点
var
用来声明变量,作用和let
相同,但是var
不具有块作用域
- 在全局中使用
var
声明的变量,都会作为window
对象的属性保存 - 使用
function
声明的函数,都会作为window
的方法保存 - 使用
let
声明的变量不会存储在window
对象中,而存在一个“秘密的小地方”(无法访问)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js讲解</title>
<script type="text/javascript">
var b = 20;//等价于window.b = 20;
function fn(){
console.log("我是fn");
}
console.log(window.b);
window.fn();
let c = 33;
console.log(window.c);
let d = 4;
window.d = 5;
console.log(d);
</script>
</head>
<body>
</body>
</html>
-
在局部作用域中,如果没有使用
var
或let
声明变量,则变量会自动成为window
对象的属性也就是全局变量<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>js讲解</title> <script type="text/javascript"> function fn(){ b = 10; } fn();//变量b在函数调用时候被创建 console.log(b);//此时的b等价于window.b,在局部作用域中,如果没有使用var或let声明变量,则变量会自动成为window对象的属性也就是全局变量 </script> </head> <body> </body> </html>
⑾ 函数和变量的提升
1)变量的提升
使用var
声明的变量,它会在所有代码执行前被声明,所以我们可以在变量声明前就访问变量
3)函数的提升
- 使用函数声明创建的函数,会在其他代码执行前被创建,所以我们可以在函数声明前调用函数
let
声明的变量实际也会提升,但是在赋值之前解释器禁止对该变量的访问
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js讲解</title>
<script type="text/javascript">
console.log(a);//只声明了,并没有赋值
var a = 11;
fn();
function fn(){
console.log("执行了fn");
}
</script>
</head>
<body>
</body>
</html>
-
debug介绍
调试如下代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>js讲解</title> <script type="text/javascript"> console.log(a); var a = 1; console.log(a); function a(){ alert(2); } console.log(a); var a = 3; console.log(a); var a = function(){ alert(4); } console.log(a); var a; console.log(a); </script> </head> <body> </body> </html>
js中debug的使用
⑿ 立即执行函数(IIFE)
立即执行的是一个匿名函数,并且它只执行一次。
格式
格式一:
(function(){ /* code / }()); // 老道推荐写法
格式二:
(function(){ / code */ })(); // 当然这种也可以
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js讲解</title>
<script type="text/javascript">
(function(){
console.log('我是一个立即执行的函数!');
}())
</script>
</head>
<body>
</body>
</html>
⒀ 函数this
的使用
1) 普通函数中this
的使用
函数在执行时,JS解析器每次都会传递进一个隐含的参数,这个参数就叫做 this
this
会指向一个对象,this
所指向的对象会根据函数调用方式的不同而不同
-
以函数形式调用时,
this
指向的是window
-
以方法的形式调用时,
this
指向的是调用方法的对象<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>js讲解</title> <script type="text/javascript"> function fn(){ console.log("普通函数"+this); } fn(); const obj1 = { name:"沙和尚", sayHello:function(){ console.log(this); } } const obj2 = { name:"孙悟空", sayHello:function(){ console.log(this); } } obj1.sayHello(); obj2.sayHello(); </script> </head> <body> </body> </html>
2) 箭头函数的this
使用
箭头函数没有自己的this,它的this由外层作用域决定。箭头函数的this与调用它的方式无关
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js讲解</title>
<script type="text/javascript">
function fn(){
console.log("fn-->",this);
}
const fn2 = ()=>{
console.log("fn2-->",this);
}
fn();
fn2();
const obj = {
name:"唐僧",
/**fn:fn,
fn2:fn2**/
//可以简写成
fn,
fn2
}
obj.fn();
obj.fn2();
</script>
</head>
<body>
</body>
</html>
⒁ 回调函数(callback
)
一个函数的参数也可以是函数,
如果将函数作为参数传递,那么我们就称这个函数为回调函数(callback
)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
/*
一个函数的参数也可以是函数,
如果将函数作为参数传递,那么我们就称这个函数为回调函数(`callback`)
*/
class Person {
constructor(name,age){
this.name = name;
this.age = age;
}
}
const personArr =[
new Person("孙悟空",18),
new Person("沙和尚",38),
new Person("红孩儿",8),
new Person("白骨精",16)
];
//将回调函数作为参数传给filter函数
function filter(arr, cb){
const newArr= [];
for(let i=0;i< arr.length; i++){
//将回调函数的结果作为条件
if(cb(arr[i])){
newArr.push(arr[i]);
}
}
return newArr;
}
//设置回调函数
function callbackfn(obj){
return obj.name === "孙悟空";
}
let result = filter(personArr,callbackfn);
console.log(personArr);
console.log(result);
</script>
</head>
<body>
</body>
</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>
<script>
/*
一个函数的参数也可以是函数,
如果将函数作为参数传递,那么我们就称这个函数为回调函数(`callback`)
如果一个函数的参数或返回值是函数,则这个函数就称为高阶函数
*/
class Person {
constructor(name,age){
this.name = name;
this.age = age;
}
}
const personArr =[
new Person("孙悟空",18),
new Person("沙和尚",38),
new Person("红孩儿",8),
new Person("白骨精",16)
];
//将回调函数作为参数传给filter函数,filter称之为高阶函数
function filter(arr, cb){
const newArr= [];
for(let i=0;i< arr.length; i++){
//将回调函数的结果作为条件
if(cb(arr[i])){
newArr.push(arr[i]);
}
}
return newArr;
}
/*设置回调函数(通常不会这么设置回调函数,回调函数一般都是匿名的)
function callbackfn(obj){
return obj.name === "孙悟空";
}
let result = filter(personArr,callbackfn);
*/
let result = filter(personArr,obj =>obj.name === "沙和尚");
console.log(personArr);
console.log(result);
result = filter(personArr,obj =>obj.age <18);
console.log(personArr);
console.log(result);
</script>
</head>
<body>
</body>
</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>
<script>
/*
希望在someFn()函数执行时,
可以记录一条日志在不修改原函数的基础上,
为其增加记录日志的功能可以通过高阶函数,来动态的生成一个新函数
*/
function someFn(){
return "hello";
}
function outer(cb){
return ()=>{
console.log("记录日志~~~~~");
return cb();
}
}
let rs = outer(someFn);
console.log(rs);
</script>
</head>
<body>
</body>
</html>
⒃ 闭包的介绍
① 什么是闭包:
闭包就是能访问到外部函数作用域中变量的函数
② 什么时候使用:
当我们需要隐藏一些不希望被别人访问的内容时就可以使用闭包
③ 构成闭包的要件:
1.函数的嵌套
2.内部函数要引用外部函数中的变量
3.内部函数要作为返回值返回
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
function outer(){
let num = 0;//位于函数作用域中
return ()=>{
num++;
console.log(num);
}
}
let newFn = outer();
console.log(newFn);
</script>
</head>
<body>
</body>
</html>
④ 闭包的生命周期
闭包的生命周期:
1.闭包在外部函数调用时产生,外部函数每次调用都会产生一个全新的闭包
2.在内部函数去失时销毁(内部函数被垃圾回收了,闭包才会消失)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
function outer(){
let num = 0;//位于函数作用域中
return ()=>{
num++;
console.log(num);
}
}
let newFn = outer();//独立闭包
let newFn2 = outer();//独立闭包
console.log(newFn());
console.log(newFn2());
//将内部函数设置为null后,会被垃圾回收掉
newFn = null;
newFn2 = null;
</script>
</head>
<body>
</body>
</html>
注意事项:
闭包主要用来隐藏一些不希望被外部访问的内容,
这就意味着闭包需要占用一定的内存空间
相较于类来说,闭包比较浪费内存空间(类可以使用原型而闭包不能)需要执行次数较少时,使用闭包,需要大量创建实例时,使用类
⒄ 递归
调用自身的函数称为递归函数,递归的作用和循环是基本一致
编写递归函数,一定要包含两个要件:
1.基线条件- 递归的终止条件
2.递归条件-如何对问题进行拆分
注意:
递归的作用和循环是一致的,不同点在于,递归思路比较清晰简洁,循环的执行性能比较好
在开发中,一般的问题都可以通过循环解决,也是尽量去使用循环,少用递归。只在一些使用循环解决比较麻烦的场景下,才使用递归
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
/*
使用循环解决阶乘问题
创建一个函数可以用来求任意数的阶乘 n!=n*(n-1)!
*/
function factorial(num){
//创建一个变量用于记录结果
let result = 1;
for(let i = 2;i<=num;i++){
result = result * i;
}
return result;
}
/*
使用递归解决阶乘问题
用递归改造上面的函数
*/
function recursion(num){
//基线条件
if(num === 1){
return 1;
}
//递归条件 n!=n*(n-1)!
return num * recursion(num - 1);
}
</script>
</head>
<body>
</body>
</html>
⒅ 函数中的隐藏参数arguments
和可变参数
① 函数中的隐藏参数arguments
arguments
是函数中又一个隐含参数
arguments
是一个类数组对象(伪数组)
和数组相似,可以通过索引来读取元素,也可以通过for循环变量,但是它不是一个数组对象,不能调用数组的方法
arguments
用来存储函数的实参
无论用户是否定义形参,实参都会存储到arguments
对象中
可以通过该对象直接访问实参
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
function fn(){
/*
函数中的隐藏参数arguments
arguments是函数中又一个隐含参数
arguments是一个类数组对象(伪数组)
和数组相似,可以通过索引来读取元素,也可以通过for循环变量,但是它不是一个数组对象,不能调用数组的方法
arguments用来存储函数的实参
无论用户是否定义形参,实参都会存储到arguments对象中
可以通过该对象直接访问实参
*/
console.log(Array.isArray(arguments));//false ,说明arguments不是一个数组
//遍历参数并且打印出来
for(let i = 0;i<arguments.length;i++){
console.log("参数值:",arguments[i]);
}
//打印arguments
console.log(arguments);
}
fn(1,3,9);
</script>
</head>
<body>
</body>
</html>
② 可变参数
可变参数,在定义函数时可以将参数指定为可变参数
- 可变参数可以接收任意数量实参,并将他们统一存储到一个数组中返回
- 可变参数的作用和arguments基本是一致,但是也具有一些不同点:
○ 可变参数的名字可以自己指定
○ 可变参数就是一个数组,可以直接使用数组的方法
○ 可变参数可以配合其他参数一起使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
/*
可变参数,在定义函数时可以将参数指定为可变参数
可变参数可以接收任意数量实参,并将他们统一存储到一个数组中返回
可变参数的作用和arguments基本是一致,但是也具有一些不同点:
○ 可变参数的名字可以自己指定
○ 可变参数就是一个数组,可以直接使用数组的方法
○ 可变参数可以配合其他参数一起使用
*/
//可变参数的名字可以自己指定,定义一个可变参数为args的函数
function fn(...args){
console.log(args);
}
//可变参数就是一个数组,可以直接使用数组的方法
//定义一个可变参数的函数,该函数的作用是求可变参数的和并返回
function fn2(...num){
return num.reduce((a,b)=>a+b,0);
}
//可变参数可以配合其他参数一起使用,但需要将可变参数写到最后
function fn3(a,b,...args){
for(value of arguments){
console.log(value);
}
console.log(args);
}
</script>
</head>
<body>
</body>
</html>
⒆ call()
和apply()
函数中
this
的使用回顾:
根据函数调用方式的不同,this的值也不同:
● 以函数形式调用,this是window
● 以方法形式调用,this是调用方法的对象
● 构造函数中,this是新建的对象
● 箭头函数没有自己的this,由外层作用域决定
● 通过call和apply调用的函数,它们的第一个参数就是函数的this
调用函数除了通过 函数()
这种形式外,还可以通过其他的方式来调用函数
比如,我们可以通过调用函数的call()
和apply()
两个方法来调用函数
函数.call()
函数.apply()
call()
和apply()
除了可以调用函数,还可以用来指定函数中的this
call()
和apply()
的第一个参数,将会成为函数的this
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
/*
call()和apply()除了可以调用函数,还可以用来指定函数中的this
call()和apply()的第一个参数,将会成为函数的this
*/
function fn(){
console.log("函数执行了~,this值为:",this);
}
const obj = {name:"孙悟空",fn}
fn.call();
fn.call(obj);
fn.apply(console);
</script>
</head>
<body>
</body>
</html>
call()
和apply()
的区别:
● 通过call()
方法调用函数,函数的实参直接在第一个参数后一个一个的列出来
● 通过apply()
方法调用函数,函数的实参需要通过一个数组传递
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
function fn(a,b){
console.log("a=",a,"b=",b,"函数执行了~,this值为:",this);
}
const obj = {name:"孙悟空",fn}
fn(false,true);
//通过call()方法调用函数,函数的实参直接在第一个参数后一个一个的列出来
fn.call(obj,"张三","李四");
//通过apply()方法调用函数,函数的实参需要通过一个数组传递
fn.apply(console,[1,2]);
</script>
</head>
<body>
</body>
</html>
⒇ bind()
函数中
this
的使用回顾:
根据函数调用方式的不同,this的值也不同:
● 以函数形式调用,this是window
● 以方法形式调用,this是调用方法的对象
● 构造函数中,this是新建的对象
● 箭头函数没有自己的this,由外层作用域决定
● 通过call和apply调用的函数,它们的第一个参数就是函数的this
● 通过bind()
返回的函数,this
由bind()
第一个参数决定(无法修改)
bind()
是函数的方法,可以用来创建一个新的函数
● bind()
可以为新函数绑定this(绑定this后,this值无法在修改)
● bind()
可以为新函数绑定参数(绑定参数后,该参数的值不可变)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
/*
bind()是函数的方法,可以用来创建一个新的函数
● bind()可以为新函数绑定this(绑定this后,this值无法在修改)
● bind()可以为新函数绑定参数(绑定参数后,该参数的值不可变)
*/
function fn(a,b,c){
console.log("a=",a,"b=",b,"c=",c,"函数执行了~,this值为:",this);
}
const obj = {name:"孙悟空",fn}
const newFun = fn.bind(obj,"张三",true);
//bind()可以为新函数绑定this(绑定this后,this值无法在修改)
//想通过call()修改newFun的this,结果无法修改
newFun.call(console);
//bind()可以为新函数绑定参数(绑定参数后,该参数的值不可变)
//想通过传三个实参的方式修改newFun绑定的参数的值,结果无法修改绑定的参数值
newFun(1,2,3);
</script>
</head>
<body>
</body>
</html>
注意:
● 箭头函数没有自身的this,它的this由外层作用域决定,也无法通过call()
、apply()
和bind()
修改它的this值
● 箭头函数中没有arguments
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
/*
● 箭头函数没有自身的this,它的this由外层作用域决定,也无法通过call()、apply()和bind()修改它的this值
● 箭头函数中没有arguments
*/
const fun = ()=>{
console.log("函数this值为:",this);
//箭头函数中没有arguments
console.log(arguments);
}
const obj = {name:"孙悟空",fun}
//箭头函数没有自身的this,它的this由外层作用域决定,也无法通过call()、apply()和bind()修改它的this值
fun.apply(obj);
</script>
</head>
<body>
</body>
</html>
13. js严格模式
js运行代码的模式有两种:
- 正常模式
○ 默认情况下代码都运行在正常模式中,在正常模式,语法检查并不严格。它的原则是:能不报错的地方尽量不报错
○ 这种处理方式导致代码的运行性能较差 - 严格模式
在严格模式下,语法检查变得严格
○ 禁止一些语法
○ 更容易报错
○ 提升了性能
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js讲解</title>
<script type="text/javascript">
//"use strict" 全局的严格模式
a = 10;
function fn(){
"use strict"//函数的严格模式
let a = 10;
b = 100;
}
fn();
</script>
</head>
<body>
</body>
</html>
14. 面向对象
⑴ 面向对象简介
- 类是对象模板,可以将对象中的属性和方法直接定义在类中。定义后,就可以直接通过类来创建对象
- 通过同一个类创建的对象,我们称为同类对象
○ 可以使用instanceof
来检查一个对象是否是由某个类创建。如果某个对象是由某个类所创建,则我们称该对象是这个类的实例
语法:
创建类的方式:
① class 类名 {} // 类名要使用大驼峰命名
② const 类名=class {}
创建对象的方式:
通过类创建对象
new 类()
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js讲解</title>
<script type="text/javascript">
//创建一个对象five
const five = {
//添加属性
name:"张三",
age:33,
heigth:180,
weight:100,
//添加方法
sleep(){
console.log(this.name+"睡觉了~");
},
eat(){
console.log(this.name+"吃饭了~");
}
}
</script>
</head>
<body>
</body>
</html>
⑵ 属性
类是创建对象的模板,要创建对象的第一件事就是定义类
注意:
① 类的代码块中默认就是严格模式
② 类的代码块中是用来设置对象的属性的,不是什么代码都能写
1)实例属性
实例属性只能通过实例去访问
2)静态属性
静态属性只能通过类去访问
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js讲解</title>
<script type="text/javascript">
class Person{
/*
类的代码块,默认就是严格模式,
类的代码块是用来设置对象的属性的,不是什么代码都能写
*/
name ="孙悟空";//Person的实例属性name p1.name//实例属性只能通过实例访问 p1.age
age = 18;
static test ="test静态属性";// 使用static声明的属性,是静态属性(类属性),静态属性只能通过类去访问 Person.test
}
const p1 = new Person();
const p2 = new Person();
console.log(p1.name+","+p1.age);
console.log(p2.name+","+p2.age);
console.log(Person.test);
</script>
</head>
<body>
</body>
</html>
⑶ 方法
对象中添加方法有两种方式
方式一
方法名 = function(){
…
}
方式二
方法名(){
…
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js讲解</title>
<script type="text/javascript">
class Person{
name = "孙悟空";
/*添加方法的的方式一
sayHello = function(){
console.log("大家好,我是"+this.name);
}*/
//添加方法(实例方法),实例方法中this就是当提实例
sayHello(){
console.log("大家好,我是"+this.name);
}
//静态方法(类方法),通过类来调用。this指向的是当前类
static test(){
console.log("我是静态方法",this);
}
}
const p1 = new Person();
console.log(p1);
console.log(p1.sayHello);
p1.sayHello();
Person.test();
</script>
</head>
<body>
</body>
</html>
⑷ 构造函数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js讲解</title>
<script type="text/javascript">
class Person{
name;
age;
gender;
//在类中可以添加一个特殊的方法constructor
//该方法我们称为构造函数(构造方法)
// 构造函数会在我们调用类创建对象时执行
constructor(name,age,gender){
//可以在构造函数中,为实例属性进行赋值
// 在构造函数中,this表示当前所创建的对象
this.name = name;
this.age = age;
this.gender =gender;
}
}
const p1 = new Person("猪八戒",12,"男");
const p2 = new Person("孙悟空",13,"男");
const p3 = new Person("唐僧",19,"男");
console.log(p1);
console.log(p2);
console.log(p3);
</script>
</head>
<body>
</body>
</html>
⑸ 面向对象的三个特点
封装——安全性
继承——扩展性
多态——灵活性
1)封装
① 封装的基本介绍
- 对象就是一个用来存储对象的容器
- 对象不仅存储属性,还要负责数据的安全
- 直接添加到对象中的属性并不安全,因为他们可以被任意的修改
- 如何确保数据的安全:
○ 私有化数据
● 将需要保护的数据设置为私有,只能在内部使用
○ 提供setter
和getter
方法来开放对数据的操作
● 属性设置私有,通过getter
和setter
方法操作属性带来的好处
■ 可以控制属性的读写权限
■ 可以在方法中对属性的值进行验证 - 封装主要用来保证数据的安全性
② 实现封装的方式
-
属性私有化,加
#
-
通过
getter
和setter
方法操作属性get 属性名(){
return this.#属性;
}set 属性名(参数){
this.#属性 = 参数;
}<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>js讲解</title> <script type="text/javascript"> class Person{ //通过使用#开头就变成了私有属性,私有属性只能在类内部访问 #name; #age; #gender; constructor(name,age,gender){ this.#name = name; this.#age = age; this.#gender =gender; } sayHello(){ console.log(this.#name); } //getter方法,用来获取属性 getName(){ return this.#name; } //setter方法,用来设置属性 setName(name){ this.#name = name; } } const p1 = new Person("猪八戒",12,"男"); console.log(p1); console.log(p1.getName()); p1.setName("唐僧") console.log(p1); console.log(p1.getName()); </script> </head> <body> </body> </html>
setter
和getter
方法的新式写法<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>js讲解</title> <script type="text/javascript"> class Person{ //通过使用#开头就变成了私有属性,私有属性只能在类内部访问 #name; #age; #gender; constructor(name,age,gender){ this.#name = name; this.#age = age; this.#gender =gender; } sayHello(){ console.log(this.#name); } //getter方法,用来获取属性 /* 通过老式的getter方法来获取属性 getName(){ return this.#name; } */ //通过新式的getter方法来获取属性 get name(){ console.log("执行了新式的getter方法"); return this.#name; } /* 通过老式的setter方法来设置属性 setName(name){ this.#name = name; } */ //通过新式的setter方法来设置属性 set name(name){ console.log("执行了新式的setter方法"); this.#name = name; } } const p1 = new Person("猪八戒",12,"男"); console.log(p1); //通过 对象.属性 的方式来调用getter方法 console.log(p1.name); //通过 对象.属性 的方式来调用setter方法 p1.name = "唐僧"; console.log(p1); console.log(p1.name); </script> </head> <body> </body> </html>
2)多态
同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果。
在JS中不会检查参数的类型,所以这就意味着任何数据都可以作为参数传递。要调用某个函数,无需指定的类型,只要对象满足某些条件即可。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js讲解</title>
<script type="text/javascript">
class Person{
constructor(name){
this.name = name;
}
}
class Dog{
constructor(name){
this.name = name;
}
}
function sayHello(obj){
console.log("Hello,"+obj.name);
}
const dog = new Dog("旺财");
const person = new Person("张三");
sayHello(dog);
sayHello(person);
</script>
</head>
<body>
</body>
</html>
3) 继承
- 可以通过extends关键字来完成继承
- 当一个类继承另一个类时,就相当于将另一个类中的代码复制到了当前类中(简单理解)
- 继承发生时,被继承的类称为父类(超类),继承的类称为子类
- 通过继承可以减少重复的代码,并且可以在不修改一个类的前提对其进行扩展
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js讲解</title>
<script type="text/javascript">
class Animal{
constructor(name){
this.name = name;
}
sayHello(){
console.log("动物在叫~");
}
}
class Dog extends Animal{
//在子类中,可以通过创建同名方法来重写父类的方法
sayHello(){
console.log("汪汪汪~");
}
}
class Cat extends Animal{
//重写构造方法,子类添加新的属性
constructor(name,age){
//重写构造函数时,构造函数的第一行代码必须为super()
super(name);
this.age = age;
}
sayHello(){
//调用一下父类的sayHello方法,在子类中可以使用super来引用父类的方法
super.sayHello();
console.log("喵喵喵~");
}
}
const dog = new Dog("旺财");
const cat = new Cat("汤姆");
console.log(dog);
dog.sayHello();
console.log(cat);
cat.sayHello();
</script>
</head>
<body>
</body>
</html>
⑹ 对象的结构
对象中存储属性的区域实际有两个:
- 对象自身
○ 直接通过对象所添加的属性,位于对象自身中
○ 在类中通过x = y
的形式添加的属性,位于对象自身中 - 原型对象(prototype)
○对象中还有一些内容,会存储到其他的对象里(原型对象)
○ 在对象中会有一个属性用来存储原型对象,这个属性叫做__proto__
○ 原型对象也负责为对象存储属性
● 当我们访问对象中的属性时,会优先访问对象自身的属性
● 对象自身不包含该属性时,才会去原型对象中寻找
○ 会添加到原型对象中的情况:
● 在类中通过xxx(){}
方式添加的方法,位于原型中
● 主动向原型中添加的属性或方法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>js学习</title>
<script>
class Person{
name = "孙悟空";
age = 18;
constructor(){
this.add = "花果山";
}
fun = ()=>{
console.log("我是一个箭头方法!");
}
sayHello() {
console.log("你好,我是"+this.name);
}
}
const p = new Person();
p.sex = "男";
console.log(p);
console.log(p.sayHello)
p.sayHello = "你好啊";
console.log(p.sayHello);
</script>
</head>
<body>
</body>
</html>
⑺ 原型对象
1) 访问一个对象的原型对象的方式
对象.__proto__
Object.getPrototypeOf(对象)
2) 原型对象中的数据
- 对象中数据(属性、方法等)
constructor
(对象的构造函数)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>js学习</title>
<script>
class Person{
name = "孙悟空";
sayHello(){
console.log("你好,我是"+this.name);
}
}
const p = new Person();
console.log(p.__proto__);//访问原型对象的方式一
console.log(Object.getPrototypeOf(p));//访问原型对象的方式二
console.log(p.__proto__ == Object.getPrototypeOf(p));
console.log(p.__proto__.constructor);
</script>
</head>
<body>
</body>
</html>
3) 原型链
原型对象也有原型,这样就构成了一条原型链,根据对象的复杂程度不同,原型链的长度也不同
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>js学习</title>
<script>
class Person{
name = "孙悟空";
sayHello(){
console.log("你好,我是"+this.name);
}
}
const p = new Person();
console.log(p.__proto__);
console.log(p.__proto__.__proto__);
console.log(p.__proto__.__proto__.__proto__);
const obj = {}
console.log(obj.__proto__);
console.log(obj.__proto__.__proto__);
</script>
</head>
<body>
</body>
</html>
obj对象的原型链: obj对象 --> 原型 -->null
p对象的原型链: p对象 --> 原型 --> 原型 --> null
注意:
原型链::
读取对象属性时,会优先对象自身属性,
如果对象中有,则使用,没有则去对象的原型中寻找如果原型中有,则使用,没有则去原型的原型中寻找直到找到Object对象的原型 (Object的原型没有原型(为null如果依然没有找到,则返回undefined
- 作用域链,是找变量的链,找不到会报错
- 原型链,是找属性的链,找不到会返回undefined
4) 原型的作用
所有的同类型对象它们的原型对象都是同一个,也就意味着同类型对象的原型链是一样
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
class Person{
name = "孙悟空";
age = 18;
sayHello(){
console.log("hello,我是"+this.name);
}
}
const p = new Person();
const p2 = new Person();
console.log(p===p2);
//所有的同类型对象它们的原型对象都是同一个,也就意味着同类型对象的原型链是一样
console.log(p.__proto__ === p2.__proto__);
</script>
</head>
<body>
</body>
</html>
原型的作用:
原型就相当于是一个公共的区域,可以被所有该类实例访问,可以将该类实例中,所有的公共属性(方法)统一存储到原型中这样我们只需要创建一个属性,即可被所有实例访问
在对象中有些值是对象独有的,像属性(name,age,gender)。每个对象都应该有自己值,但是有些值对于每个对象来说都是一样的,像各种方法,对于一样的值没必要重复的创建
js中继承就是通过原型来实现的,当集成时,子类的原型就是一个父类的实例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
class Animal{
}
class Cat extends Animal{
}
/**
* 继承对象的原型链
* cat对象——>父对象Animal对象——>obj对象——>obj对象原型——>null
* */
const cat = new Cat();
console.log(cat);
console.log(cat.__proto__);
console.log(cat.__proto__.__proto__);
console.log(cat.__proto__.__proto__.__proto__);
console.log(cat.__proto__.__proto__.__proto__.__proto__);
</script>
</head>
<body>
</body>
</html>
5) 如何修改原型
① 通过类的实例去修改原型(千万不要这么做!!!
)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
class Person{
name = "孙悟空";
age = 18;
sayHello(){
console.log("helllo,我是"+this.name);
}
}
const p = new Person();
const p2 = new Person();
//通过对象修原型,向原型中添加方法,修改后所有的同类实例都能访问该方法
p.__proto__.run = ()=>{
console.log("我在跑~");
}
p.run();
p2.run();
class Dog{
}
//直接为对象赋值一个新的原型
p.__proto__ = new Dog();
console.log(p);
console.log(p2);
</script>
</head>
<body>
</body>
</html>
注意:
千万不要通过类的实例去修改原型
- 通过一个对象影响所有同类对象,这么做不合适
- 修改原型先得创建实例,麻烦
- 危险
② 通过类的prototype属性来修改原型
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
class Person{
name = "孙悟空";
age = 18;
sayHello(){
console.log("helllo,我是"+this.name);
}
}
//通过类中的prototype属性修改原型
Person.prototype.run = ()=>{
console.log("我在跑~");
}
const p = new Person();
const p2 = new Person();
console.log(p.__proto__ === Person.prototype);//通过对象获取原型和通过类的属性获取原型是同一个原型
console.log(p);
p.run();
p2.run();
</script>
</head>
<body>
</body>
</html>
修改原型时,最好通过通过类去修改。好处:
1.一修改就是修改所有实例的原型
2.无需创建实例即可完成对类的修改
6) instanceof
、in
和hasOwn
介绍
① instanceof
介绍
instanceof用于检查一个对象是否是另一个类的实例
只要原型链上有该实例就会返回true
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
class Animal{
}
class Dog extends Animal{
}
const dog = new Dog();
console.log(dog instanceof Dog);//true
console.log(dog instanceof Animal);//true
console.log(dog instanceof Object);//true
//dog实例 ->Animal的实例 ->0bject实例 -> Object原型
console.log(dog);
console.log(dog.__proto__);
console.log(dog.__proto__.__proto__);
console.log(dog.__proto__.__proto__.__proto__);
</script>
</head>
<body>
</body>
</html>
② in
介绍
使用in运算符检查属性时,无论属性在对象自身还是在原型中,都会返回true
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
class Person{
name = "孙悟空";
age = 18;
sayHello(){
console.log("helllo,我是"+this.name);
}
}
const p = new Person();
console.log("name" in p);
console.log("sayHello" in p);
</script>
</head>
<body>
</body>
</html>
③ hasOwn
介绍
-
对象.hasOwnProperty(属性名)(不推荐使用)
用来检查一个对象的自身是否含有某个属性 (不包含原型中的属性)<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script> class Person{ name = "孙悟空"; age = 18; sayHello(){ console.log("helllo,我是"+this.name); } } const p = new Person(); console.log("name" in p); /** * 对象.hasOwnProperty(属性名)(不推荐使用) * 用来检查一个对象的自身是否含有某个属性 **/ console.log(p.hasOwnProperty("sayHello")); console.log(p.__proto__.__proto__); console.log(p.__proto__.__proto__.hasOwnProperty("sayHello"));//说明hasOwnProperty方法在Object的原型中 </script> </head> <body> </body> </html>
-
Object.hasOwn(对象,属性名)
用来检查一个对象的自身是否含有某个属性 (不包含原型中的属性)<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script> class Person{ name = "孙悟空"; age = 18; sayHello(){ console.log("helllo,我是"+this.name); } } const p = new Person(); //使用in运算符检查属性时,无论属性在对象自身还是在原型中,都会返回true console.log("name" in p);//true console.log("sayHello" in p);//true /** * Object.hasOwn(对象,属性名) * 用来检查一个对象的自身是否含有某个属性 **/ console.log(Object.hasOwn(p,"name"));//true console.log(Object.hasOwn(p,"sayHello"));//false </script> </head> <body> </body> </html>
⑻ 旧类(早期类的定义方式)
早期JS中,直接通过函数来定义类
- 一个函数如果直接调用
xxx()
那么这个函数就是一个普通函数 - 一个函数如果通过new调用
new xxx()
那么这个函数就是一个构造函数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
//通过老的方法定义的类一般会放在一个立即执行函数里面
var Person = (function(){
/*
等价于
class Person{
}
*/
function Person(name,age){
this.name = name;
this.age = age;
}
//向原型中添加添加属性(方法)
Person.prototype.sayHello = () =>{
console.log("你好,我是"+this.name);
}
//添加静态属性
Person.staticProperty = "李四";
//添加静态方法
Person.staticMethod = ()=>{
console.log("我是静态方法~");
}
return Person;
})()
Person();
const p = new Person("张三",19);
console.log(p);
Person.staticMethod();
console.log(Person.staticProperty);
</script>
</head>
<body>
</body>
</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>
<script>
var Animal = (function(){
function Animal(){
}
return Animal;
})()
var Cat = (function(){
function Cat(){
}
//继承Animal
Cat.prototype = new Animal();
return Cat;
})()
var cat = new Cat();
console.log(cat);
console.log(cat instanceof Cat);
console.log(cat instanceof Animal);
</script>
</head>
<body>
</body>
</html>
⑼ new 运算符
new运算符是创建对象时要使用的运算符
使用new时,到底发生了哪些事情:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/0perators/new
当使用new去调用一个函数时,这个函数将会作为构造函数调用,使用new调用函数时,将会发生这些事:
1.创建一个普通的JS对象(0bject对象 {}),为了方便,称其为新对象
2.将构造函数的prototype属性设置为新对象的原型
3.如果构造函数有实参,使用实参来执行构造函数,并且将新对象设置为函数中的this.
4.如果构造函数返回的是一个非原始值,则该值会作为new运算的返回值返回
如果构造函数的返回值是一个原始值或者没有指定返回值,
则新的对象将会作为返回值返回
在JavaScript中,原始值(primitive value)是指那些不是对象的值。
原始类型有五种:undefined、null、boolean、number和string。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
/*
1.创建一个普通的JS对象(0bject对象 {}),为了方便,称其为新对象
2.将构造函数的prototype属性设置为新对象的原型
3.使用实参来执行构造函数,并且将新对象设置为函数中的this.
4.如果构造函数返回的是一个非原始值,则该值会作为new运算的返回值返回(千万不要这么做)
如果构造函数的返回值是一个原始值或者没有指定返回值,
则新的对象将会作为返回值返回
*/
class MyClass{
//var newInstance = {}//1.创建一个普通的JS对象(0bject对象 {}),为了方便,称其为新对象
//new newInstance.__proto__ = MyClass.prototype;//2.将构造函数的prototype属性设置为新对象的原型
constructor(){
return {};
}
}
const myclass = new MyClass();
console.log(myclass);
</script>
</head>
<body>
</body>
</html>
⑽ 对象的分类
15. 数组(Array)
1)数组的简介
数组也是一种复合数据类型,在数组可以存储多个不同类型的数据数组中存储的是有序的数据,数组中的每个数据都有一个唯一的索引可以通过索引来操作获取数据,数组中存储的数据叫做元素
2) 索引(index)
索引是一组大于0的整数
3)创建数组
通过Array()来创建数组,也可以通过[]来创建数组
4)向数组中添加元素
语法:
数组[索引]= 元素
如果读取了一个不存在的元素,不好报错而是返回undefined
5)数组的属性
① length
获取数组的长度
1.实际上
length
获取的是最大索引+1
2.最大索引+1向数组最后添加元素:
数组[数组.length]= 元素
3.length是可以修改的
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
const arr = new Array();
const arr2 = [10,22,44,88];
arr[0]= 10;
arr[1]=22;
arr[2]=44;
arr[3]= 88;
arr2[3]=99;
arr2[100] = 100; //使用数组时,应该避免非连续数组,因为它性能不好
console.log(arr);
console.log(arr2);
console.log(arr[2]);
console.log(arr[100]);//如果读取了一个不存在的元素,不好报错而是返回undefined
console.log(typeof arr);//object
console.log(arr2.length);//101
console.log(arr.length);//4
arr[arr.length] = 88;
console.log(arr);
arr.length = 100;//修改数组长度,比原数组长度大,则通过空值补充
console.log(arr);
arr.length = 1;//修改数组长度,比元素组小,则删除多余的内容
console.log(arr);
</script>
</head>
<body>
</body>
</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>
<script>
//任何类型的值都可以成为数组中的元素
let arr =[1,"hello",true, null,{name:"孙悟空"},( )=>{}]
console.log(arr);
</script>
</head>
<body>
</body>
</html>
注意:
任何类型的值都可以成为数组中的元素,但是创建数组时尽量要确保数组中存储的数据的类型是相同
6)数组的遍历
① 传统for
循环遍历数组
遍历数组简单理解,就是获取到数组中的每一个元素
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
let arr = ["孙悟空","猪八戒","沙和尚","唐僧","白骨精"];
console.log(arr);
//数组正序遍历
for(let i = 0;i<arr.length;i++){
console.log(arr[i]);
}
console.log("---------------------------------------");
//数组倒序遍历
for(let i = arr.length -1;i>=0;i--){
console.log(arr[i]);
}
</script>
</head>
<body>
</body>
</html>
② for-of
遍历可迭代的对象
语法:
for(变量 of 可迭代的对象){
语句…
}
执行流程:
for-of
的循环体会执行多次,数组中有几个元素就会执行几次,每次执行时都会将一个元素赋值给变量
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
//for-of遍历数组
const arr = ["孙悟空","猪八戒","沙和尚","唐僧","白骨精"];
for(let value of arr){
console.log(value);
}
console.log("-------------------------");
//for-of遍历字符串
for(let value of "hello"){
console.log(value);
}
</script>
</head>
<body>
</body>
</html>
7)数组方法的介绍
https://developer.mozilla.org/en-Us/docs/Web/JavaScript/Reference/Global_0bjects/Array
① Array.isArray()
用来检查一个对象是否是数组
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
const arr = ["孙悟空","猪八戒","沙和尚","唐僧","白骨精"];
console.log(Array.isArray(arr));
console.log(Array.isArray("hello"));
</script>
</head>
<body>
</body>
</html>
② at(参数)
可以根据索引获取数组中的指定元素,at可以接收负索引作为参数,表示倒数第几个元素
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
const arr = ["孙悟空","猪八戒","沙和尚","唐僧","白骨精"];
console.log(arr.at(1));
console.log(arr.at(-2));
</script>
</head>
<body>
</body>
</html>
③ concat()
用于拼接两个或多个数组
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
const arr = ["孙悟空","猪八戒","沙和尚","唐僧","白骨精"];
const arr2 = ["牛魔王","红孩儿"];
console.log(arr.concat(arr2,["铁扇公主","紫霞仙子"]));
console.log(arr);
</script>
</head>
<body>
</body>
</html>
concat()是非破坏性的方法,只会生成新的数组,不会改变原来数组
④ indexOf()
和lastIndexOf()
indexOf()
● 获取元素在数组中第一次出现的索引
●参数:
○ 要查询的元素
○ 查询的起始位置lastIndexOf()
获取元素在数组中最后一次出现的位置
●参数:
○ 要查询的元素
○ 查询的起始位置- 返回值:
找到了则返回元素的索引,没有找到返回-1
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
const arr = ["孙悟空","猪八戒","沙和尚","唐僧","白骨精","沙和尚"];
console.log(arr.indexOf("沙和尚"));
console.log(arr.indexOf("沙和尚",3));
console.log(arr.lastIndexOf("沙和尚"));
console.log(arr.lastIndexOf("沙和尚", 1));
</script>
</head>
<body>
</body>
</html>
⑤ join()
将一个数组中的元素连接为一个字符串
例如:["孙牾空”,“猪八戒”,“沙和尚”,“唐僧”,“沙和尚”]——>"孙悟空,猪八戒,沙和尚,唐僧,沙和尚
参数:
指定一个字符串作为连接符
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
const arr = ["孙悟空","猪八戒","沙和尚","唐僧","白骨精","沙和尚"];
console.log(arr.join())
console.log(arr.join("——>"))
</script>
</head>
<body>
</body>
</html>
⑥ slice()
用来截取数组(非破坏性方法)
- 参数:
○ 参数1 截取的起始位置(包括该位置)
○ 参数2 截取的结束位置(不包括该位置)
○ 第二个参数可以省略不写,如果省略则会一直截取到最后
○ 索引可以是负值,表示倒数第几个
○ 如果将两个参数全都省略,则可以对数组进行浅拷贝(浅复制)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
const arr = ["孙悟空","猪八戒","沙和尚","唐僧","白骨精","沙和尚"];
console.log(arr.slice(1,3));
console.log(arr.slice(1,-2));
console.log(arr.slice(1));
console.log(arr.slice());
console.log(arr);
</script>
</head>
<body>
</body>
</html>
⑦ push()
向数组的末尾添加一个或多个元素并返回新数组的长度
⑧ pop()
删除数组中最后一个元素,并返回该元素的值
⑨ unshift()
向数组的开头添加一个或多个元素并返回新数组的长度
⑩ shift()
删除数组中第一个元素,并返回该元素的值
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
/*
push()
-向数组的末尾添加一个或多个元素并返回新数组的长度
pop()
-删除数组中最后一个元素,并返回该元素的值
unshift()
-向数组的开头添加一个或多个元素并返回新数组的长度
shift()
-删除数组中第一个元素,并返回该元素的值
*/
const arr = ["唐僧","猪八戒","白骨精"];
console.log(arr);
result = arr.push("孙悟空");
console.log(arr);
console.log(result);
result = arr.pop();
console.log(arr);
console.log(result);
result = arr.unshift("牛魔王");
console.log(arr);
console.log(result);
result = arr.shift();
console.log(arr);
console.log(result);
</script>
</head>
<body>
</body>
</html>
⑪ splice()
可以删除、插入、替换数组中的元素
参数:
1.删除的起始位置
2.删除的数量
3.要插入的元素
返回值:
返回被删除的元素
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
/*
splice()
-可以删除、添加、插入、替换数组中的元素
参数:
1.删除的起始位置
2.删除的数量
3.要插入的元素
返回值:
返回被删除的元素
*/
const arr = ["唐僧","猪八戒","白骨精"];
console.log("原始数据:",arr);
//从索引为1的元素开始删除一个元素
result = arr.splice(1,1);
console.log(result);
console.log("处理后的数据:",arr);
//从索引为1的元素开始插入三个元素
console.log("原始数据:",arr);
result = arr.splice(1,0,"贾宝玉","林黛玉");
console.log(result);
console.log("处理后的数据:",arr);
//从索引为1的元素替换为三个元素
console.log("原始数据:",arr);
result = arr.splice(1,1,"牛魔王","铁扇公主");
console.log(result);
console.log("处理后的数据:",arr);
</script>
</head>
<body>
</body>
</html>
⑫ reverse()
反转数组
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
var arr = ["a","b","c","d"];
console.log("原始数组:",arr);
arr.reverse();
console.log("反转后的数组:",arr);
</script>
</head>
<body>
</body>
</html>
⑬ sort()
sort()
用来对数组进行排序(会对改变原数组)
sort()
默认会将数组升序排列
参数:
可以传递一个回调函数作为参数,通过回调函数来指定排序规则
(a,b)=>a-b 升序排列
(a,b)=>b-a 降序排列
注意:
sort()
默认会按照Unicode
编码进行排序,所以如果直接通过sort()
对数字进行排序可能会得到一个不正确的结果。可以通过传递一个回调函数作为参数解决该问题
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
/*
sort()默认会按照Unicode编码进行升序排序,
所以如果直接通过sort()对数字进行排序可能会得到一个不正确的结果。
可以通过传递一个回调函数作为参数解决该问题
*/
let arr = [3,0,3,6,10,11,56,5,4,2,8]
console.log("排序前的数字:",arr);
//按照Unicode编码进行升序排序
arr.sort();
console.log("排序后的数字:",arr);
//通过通过传递一个回调函数作为参数解决按数值大小进行升序排序
let arr2 = [3,0,3,6,10,11,56,5,4,2,8]
console.log("排序前的数字:",arr2);
arr2.sort((a,b)=>a-b);
console.log("排序后的数字:",arr2);
//通过通过传递一个回调函数作为参数解决按数值大小进行升序排序
let arr3 = [3,0,3,6,10,11,56,5,4,2,8]
console.log("排序前的数字:",arr3);
arr3.sort((a,b)=>b-a);
console.log("排序后的数字:",arr3);
let arr4 = ['a','c','b','d','f','e'];
console.log("排序前的数字:",arr4);
arr4.sort();
console.log("排序后的数字:",arr4);
</script>
</head>
<body>
</body>
</html>
⑭ forEach()
用来遍历数组
它需要一个回调函数作为参数,这个回调函数会被调用多次
数组中有几个元素,回调函数就会调用几次
每次调用,都会将数组中的数据作为参数传递
回调函数中有三个参数(这三个参数是非必填的):
element
当前的元素index
当前元素的索引array
被遍历的数组
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
/*
forEach( )
用来遍历数组
它需要一个回调函数作为参数,这个回调函数会被调用多次
数组中有几个元素,回调函数就会调用几次
每次调用,都会将数组中的数据作为参数传递
回调函数中有三个参数:
element 当前的元素
index 当前元素的索引
array 被遍历的数组
*/
let arr = ["猪八戒","孙悟空","唐僧","白龙马","沙和尚"];
arr.forEach((element,index,arr)=>{
console.log(arr);
console.log(index,"——>",element)
});
</script>
</head>
<body>
</body>
</html>
⑮ filter()
将数组中符合条件的元素过滤并保存到一个新数组中返回
需要一个回调函数作为参数,会为每一个元素去调用回调函数,并根据返回值来决定是否将元素添加到新数组中
非破坏性方法,不会影响原数组
回调函数中有三个参数(这三个参数是非必填的):
element
当前的元素index
当前元素的索引array
被遍历的数组
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
/*
filter()
将数组中符合条件的元素过滤并保存到一个新数组中返回
需要一个回调函数作为参数,会为每一个元素去调用回调函数,并根据返回值来决定是否将元素添加到新数组中
非破坏性方法,不会影响原数组
回调函数中有三个参数(这三个参数是非必填的):
element 当前的元素
index 当前元素的索引
array 被遍历的数组
*/
let arr = [9,3,4,6,2,0];
//获取数组中所有的偶数
let result = arr.filter((element)=>element % 2 === 0);
console.log("获取数组中所有的偶数:",result);
/*
回调函数中有三个参数(这三个参数是非必填的):
element 当前的元素
index 当前元素的索引
array 被遍历的数组
*/
let rs = arr.filter((element,index,arr) =>{
console.log("元素值:",element);
console.log("元素下标:",index);
console.log("数组:",arr);
});
</script>
</head>
<body>
</body>
</html>
⑯ map()
根据当前数组生成一个新数组
需要一个回调函数作为参数,回调函数的返回值会成为新数组中的元素
非破坏性方法不会影响原数组
回调函数中有三个参数(这三个参数是非必填的):
element
当前的元素index
当前元素的索引array
被遍历的数组
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
/*
map()
根据当前数组生成一个新数组
需要一个回调函数作为参数,回调函数的返回值会成为新数组中的元素
非破坏性方法不会影响原数组
回调函数中有三个参数(这三个参数是非必填的):
element 当前的元素
index 当前元素的索引
array 被遍历的数组
*/
let arr = ["猪八戒","孙悟空","唐僧","白龙马","沙和尚"];
//给所有的名字前面加上 "西游记中的人物:"
let result = arr.map((element)=>"西游记中的人物:"+element);
console.log("获取数组中所有的偶数:",result);
/*
回调函数中有三个参数(这三个参数是非必填的):
element 当前的元素
index 当前元素的索引
array 被遍历的数组
*/
let rs = arr.filter((element,index,arr) =>{
console.log("元素值:",element);
console.log("元素下标:",index);
console.log("数组:",arr);
});
</script>
</head>
<body>
</body>
</html>
⑰ reduce()
可以用来将一个数组中的所有元素整合为一个值
参数:
- 回调函数,通过回调函数来指定合并的规则
- 可选参数,初始值
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
/*
reduce()
可以用来将一个数组中的所有元素整合为一个值
参数:
回调函数,通过回调函数来指定合并的规则
可选参数,初始值
*/
let arr = [1,2,3,4,5,6];
//将数组值全部相加后返回
let result = arr.reduce((a,b)=>a+b);
console.log(result);
//添加一个初始值为10,并将数组值全部相加后返回
result = arr.reduce((a,b)=>a+b,10);
console.log(result);
</script>
</head>
<body>
</body>
</html>
8)对象的复制
① 对象的拷贝介绍
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
const arr = ["孙悟空","猪八戒","沙和尚"];
const arr2 = arr;
arr2[1] = "唐僧";//导致arr和arr2都改变了,并不是复制
console.log(arr);
console.log(arr2);
</script>
</head>
<body>
</body>
</html>
通过slice()
对象复制
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
const arr = ["孙悟空","猪八戒","沙和尚"];
const arr2 = arr.slice();
arr2[1] = "唐僧";//只有arr发生复制,arr2改变对arr没有影响
console.log(arr);
console.log(arr2);
</script>
</head>
<body>
</body>
</html>
② 深拷贝和浅拷贝
● 对象的浅拷贝(shallow copy)
通常对对象的拷贝都是浅拷贝,浅拷贝顾名思义,只对对象的浅层进行复制(只复制一层)如果对象中存储的数据是原始值,那么拷贝的深浅是不重要的。浅拷贝只会对对象本身进行复制,不会复制对象中的属性(或元素)
通常用slice()
进行浅拷贝
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
const arr = [{name:"孙悟空"},{name:"猪八戒"}];
const arr2 = arr.slice();//浅拷贝
arr2[1] = {name:"唐僧"};
console.log(arr);
console.log(arr2);
arr[0].name = "牛魔王";
console.log(arr);
console.log(arr2);
</script>
</head>
<body>
</body>
</html>
● 对象的深拷贝(deep copy)
深拷贝指不仅复制对象本身,还复制对象中的属性和元素。因为性能问题,通常情况不太使用深拷贝
通常通过structuredClone(对象)
进行深拷贝
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
const arr = [{name:"孙悟空"},{name:"猪八戒"}];
const arr2 = arr.slice();//浅拷贝
arr2[1] = {name:"唐僧"};
console.log(arr);
console.log(arr2);
arr[0].name = "牛魔王";
console.log(arr);
console.log(arr2);
console.log("-----------------------------------------------------");
const array = [{name:"林黛玉"},{name:"贾宝玉"}];
const array2 = structuredClone(array);//深拷贝
array[1] = {name:"贾乃亮"};
console.log(array);
console.log(array2);
array[0].name = "李小璐";
console.log(array);
console.log(array2);
</script>
</head>
<body>
</body>
</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>
<script>
const arr = ["孙悟空","猪八戒","沙和尚"]
/* ...(展开运算符)
可以将一个数组中的元素展开到另一个数组中或者作为函数的参数传递,通过它也可以对数组进行浅复制
*/
//const arr3=[arr[0],arr[1],arr[2]]
//const arr3 =[...arr];
const arr3 =["唐僧",...arr,"白骨精"]
console.log(arr)
console.log(arr3)
function sum(a,b,c){
return a+b+c;
}
const arr4=[10,20,30]
//let result =sum(arr4[0],arr4[1],arr4[2]);
result =sum(...arr4)
console.log(result)
</script>
</head>
<body>
</body>
</html>
● 对象通过展开运算符(...
)和assign()
进行复制
对象的复制
○ 0bject.assign(目标对象,被复制的对象)
○ 将被复制对象中的属性复制到目标对象里,并将目标对象返回,也可以使用展开运算符对对象进行复制
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
/*
○ 0bject.assign(目标对象,被复制的对象)
○ 将被复制对象中的属性复制到目标对象里,并将目标对象返回,也可以使用展开运算符对对象进行复制
*/
const obj = {name:"孙悟空",age:19};
const obj2 = Object.assign({},obj);
const obj3 ={address:"花果山",age:28};
const obj4 = Object.assign(obj3,obj);
console.log(obj);
console.log(obj2);
console.log(obj4);
console.log("-------------------------------------------");
const obj5 = {address:"高老庄",...obj,age:100}
console.log(obj5);//将obj中的属性在新对象中展开
</script>
</head>
<body>
</body>
</html>
二、javascript高级
1. javascript中内嵌对象
⑴ 数组的解构
1)解构赋值
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
/*
解构赋值
*/
const arr = ["张三","李四","王五"];
let a,b,c;
/*
a = arr[0];
b = arr[1];
c = arr[2];
*/
//上面的代码等价于
[a,b,c] = arr;//解构赋值
console.log("a=",a,"b=",b,"c=",c);
//解构赋值:声明的变量和赋值的元素一样多
let [d,e,f,g] = ["孙悟空","唐僧","沙和尚","猪八戒"]
console.log("d=",d,"e=",e,"f=",f,"g=",g);
//解构赋值:声明的变量比赋值的元素多
let [h,i,j] = ["林黛玉","贾宝玉"];
console.log("h=",h,"i=",i,"j=",j);
//解构赋值:声明的变量比赋值的元素多
//可以通过赋初始值的方式避免变量值为undefined
//如果解构赋值了就为解构赋的值,没有则为初始值
let [k,l="黑熊精",m="玉兔精"] = ["牛魔王","铁扇公主"];
console.log("k=",k,"l=",l,"m=",m);
//解构赋值:声明的变量比赋值的元素少
let [a1,a2] = ["语文","数学","英语"];
//解构赋值元素多出的部分直接舍去
console.log("a1=",a1,"a2=",a2);
//解构赋值:声明的变量比赋值的元素少
//可以通过可变参数的方式将多出的部分以数组的方式赋值给最后一个元素
let [b1,b2,...b3] = ["给排水","会计","计算机","土木"];
console.log("b1=",b1,"b2=",b2,"b3=",b3);
//通过解构赋值的方式交换两个变量的值
let num1 = 10;
let num2 = 20;
[num1,num2] = [num2,num1];
console.log("num1=",num1,"num2=",num2);
</script>
</head>
<body>
</body>
</html>
⑵ 对象的解构
1) 对象的解构赋值
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
/*
解构赋值
*/
const obj = {name:"张三",age:19,sex:"男"};
//声明变量同时解构赋值,在不起别名的情况下要赋值的变量名称要和对象的属性一致
let {name,age,sex} = obj;
console.log("name=",name,"age=",age,"sex=",sex);
//先声明变量后解构赋值
const object = {role:"管理员",address:"北京市",gender:"女"};
let role,address,gender;
//因为在js中以 { 开始的代码默认为代码块,不会识别为对象,所以得用()括起来
({role,address,gender} = object);
console.log("role=",role,"address=",address,"gender=",gender);
//解构赋值的对象中没有的属性,默认赋值为undefined
let {id} = obj;
console.log("id=",id);
//如果声明的对象和解构对象的属性名称不一致,可以通过起别名的形式赋值
let a,b,c,d;
({class:a,grade:b,subject:c,teacher:d="李老师"} = {class:"一班",grade:99,subject:"语文"})
console.log("a=",a,"b=",b,"c=",c,"d=",d);
</script>
</head>
<body>
</body>
</html>
⑶ 对象的序列化,内嵌对象JSON
1) 通过内嵌对象JSON将对象进行序列化
对象的序列化
● JS中的对象使用时都是存在于计算机的内存中的
● 序列化指将对象转换为一个可以存储的格式
在JS中对象的序列化通常是将一个对象转换为字符串(JSON字符串)
● 序列化的用途(对象转换为字符串有什么用):
○ 对象转换为字符串后,可以将字符串在不同的语言之间进行传递,甚至人可以直接对字符串进行读写操作,使得JS对象可以在不同的语言之间传递
○ 用途:
■ 作为数据交换的格式
■ 用来编写配置文件
● 如何进行序列化:
○ 在JS中有一个工具类 JS0N(JavaScript 0bject Notation)
JS对象表示法
○ JS对象序列化后会变成一个字符串,这个字符串我们称其为JSON字符串
● 也可以手动的编写JSON字符串,在很多程序的配置文件就是使用JSON编写的
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
/*
对象的序列化
● JS中的对象使用时都是存在于计算机的内存中的
● 序列化指将对象转换为一个可以存储的格式
在JS中对象的序列化通常是将一个对象转换为字符串(JSON字符串)
● 序列化的用途(对象转换为字符串有什么用):
○ 对象转换为字符串后,可以将字符串在不同的语言之间进行传递,甚至人可以直接对字符串进行读写操作,使得JS对象可以在不同的语言之间传递
○ 用途:
■ 作为数据交换的格式
■ 用来编写配置文件
● 如何进行序列化:
○ 在JS中有一个工具类 JS0N(JavaScript 0bject Notation) JS对象表示法
○ JS对象序列化后会变成一个字符串,这个字符串我们称其为JSON字符串
● 也可以手动的编写JSON字符串,在很多程序的配置文件就是使用JSON编写的
*/
const obj = {
name:"张三",
age:19,sex:"男"
};
console.log("obj对象序列化前:",typeof obj,obj);
//将对象obj转换为JSON字符串
const str = JSON.stringify(obj);//JSON.stringify()可以将一个对象转换成JSON字符串
console.log("obj对象序列化后" ,typeof str,str);
//将JSON字符串转换成对象obj
const object = JSON.parse(str);//JSON.parse() 可以将一个JSON格式的字符串转换成JS对象
console.log("JSON格式的字符串转换成JS对象",typeof object,object);
//也可以手动的编写JSON字符串,在很多程序的配置文件就是使用JSON编写的, JSON字符串的属性名必须使用双引号引起来
const jsonStr = '{"name":"李四"}';
const objStr = JSON.parse(jsonStr);
console.log(typeof objStr,objStr);
const jsonArr = '["张三","王五"]';
const objArr = JSON.parse(jsonArr);
console.log(typeof objArr,objArr);
console.log(objArr[0]);
</script>
</head>
<body>
</body>
</html>
编写JSON的注意事项:
- JSON字符串有两种类型:
JSON对象{}
JSON数组[]
- JSON字符串的属性名必须使用双引号引起来
- JSON中可以使用的属性值(元素)
● 数字(Number
)
● 字符串(String
) 必须使用双引号
● 布尔值(Boolean
)
● 空值(Null
)
● 对象(0bject {}
)
● 数组(Array[]
)- JSON的格式和JS对象的格式基本上一致的
注意:JSON字符串如果属性是最后一个,则不要再加,
2) 通过内嵌对象JSON进行对象深复制
① 对象深复制和浅复制回顾
-
对象浅复制
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script> const obj = { name:"孙悟空", friend:{ name:"牛魔王" } }; //对obj进行浅复制 const obj2 = Object.assign({},obj); </script> </head> <body> </body> </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> <script> const obj = { name:"孙悟空", friend:{ name:"牛魔王" } }; //对obj进行深复制 const obj2 = structuredClone(obj); </script> </head> <body> </body> </html>
② 利用JSON实现对象的深复制
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
const obj = {
name:"孙悟空",
friend:{
name:"牛魔王"
}
};
//利用JSON实现对象的深复制
const obj2 = JSON.parse(JSON.stringify(obj));
</script>
</head>
<body>
</body>
</html>
⑷ 内嵌对象Map
● Map用来存储键值对结构的数据(key-value
)
● 0bject中存储的数据就可以认为是一种键值对结构
● Map和Obiect的主要区别:
○ 0bject中的属性名只能是字符串或符号,如果传递了一个其他类型的属性名,JS解释器会自动将其转换为字符串
○ Map中任何类型的值都可以称为数据的key
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
const obj2 = {};
const obj = {
name:"孙悟空",
'age':18,
[Symbol()]:"哈哈",
[obj2]:"嘻嘻"//obj2对象类型最终会转换成字符串类型
};
console.log(obj);
</script>
</head>
<body>
</body>
</html>
Map的属性和方法
map.size
获取map中键值对的数量
map.set(key,value)
向map中添加键值对
map.get(key)
根据key获取值
map.delete(key)
删除指定数据
map.has(key)
检查map中是否包含指定键
map.clear()
删除全部的键值对
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
/*
Map中任何类型的值都可以称为数据的key
Map的方法
map.size()获取map中键值对的数量
map.set(key,value)向map中添加键值对
map.get(key)根据key获取值
map.delete(key)删除指定数据
map.has(key)检查map中是否包含指定键
map.clear()删除全部的键值对
*/
//创建一个Map对象
obj2 = {};
const map = new Map();
map.set("name","孙悟空");
map.set(NaN,"不是个数字");
map.set(obj2,"不是个数字");
console.log(map);
</script>
</head>
<body>
</body>
</html>
● Map与数组的转换
○Array.from(map)
○[...map]
● 手写Map
map可以看成两个数组
const map2 = new Map([
[“name”,“猪八戒”],
[“age”,18],
[{},()=>{}]
]);
● 遍历map
○ 方式一:通过普通循环和解构赋值实现map的遍历
○ 方式二:通过forEach遍历map
● 获取所有的key值
map.keys()
● 获取所有的value值
map.values()
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
const map = new Map();
map.set("name","孙悟空");
map.set({},"哈哈");
map.set("age",19);
console.log(map);
//Map转换成数组
const arr = Array.from(map);// [['name', '孙悟空'],[{…}, '哈哈'],['age', 19]]
const arr2 = [...map];
//手写Map
const map2 = new Map([
["name","猪八戒"],
["age",18],
[{},()=>{}]
]);
console.log(map2);
//遍历map
//方式一:通过普通循环和解构赋值实现map的遍历
console.log("map2值为",map2);
for(const [key,value] of map2){
console.log("key值",key,"value值",value);
}
console.log("----------------------------------------------------------------------");
//方式二:通过forEach遍历map
map.forEach((value,key,map)=>{
console.log("map值为",map);
console.log("key值",key,"value值",value);
});
//返回一个新的包含 [key,value] 的 Iterator 对象,返回的迭代器的迭代顺序与 Map 对象的插入顺序相同
const map3 = map.entries();
console.log(map3);
//获取所有的key值
console.log(map.keys());
//获取所有的value值
console.log(map.values());
</script>
</head>
<body>
</body>
</html>
⑸ 内嵌对象Set
Set用来创建一个集合,它的作用和数组类似,不同点在于Set中不能存储重复的数据
● 使用方式
○ 创建方式:
■ new Set();
■ new Set([...]);
○ 属性和方法
■ size
获取数量
■ add()
添加元素
■ has()
检查元素
■ delete()
删除元素
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
//创建一个Set
const set = new Set();
//向Set中添加元素
set.add(10);
set.add("孙悟空");
set.add(10);
console.log(set);
//通过Set给数组去重
const arr = [1,2,2,3,3,3,4,5,5,6,7,7,7,7,8,9,9];
const set2 = new Set(arr);
const arr2 = Array.from(set2);
console.log(arr2);
//size 获取数量
console.log(set.size);
//has()检查元素
console.log(set.has("孙悟空"));
//delete()删除元素
set.delete("孙悟空");
console.log(set);
</script>
</head>
<body>
</body>
</html>
⑹ 内嵌对象Math
Math
是一个工具类,他为我们提供了数学运算相关的一些常量和方法
● 常量:
Math.PI
圆周率
● 方法:
Math.abs()
求一个数的绝对值
Math.min()
求多个值中的最小值
Math.max()
求多个值中的最大值
Math.pow()
求x的y次幂
Math.sqrt()
求一个数的平方根
Math.floor()
向下取整
Math.ceil()
向上取整
Math.round()
四舍五入取整
Math.trunc()
直接去除小数位
Math.random()
生成一个0-1之间的随机数
⑺ 内嵌对象Date
1)内嵌对象Date
的介绍
在JS中所有的和时间相关的数据部由Date
对象来表示
对象的方法:
getFullYear()
获取4位年份
getMonth()
返当前日期的月份(0-11)
getDate()
返回当前是几日
getDay()
返回当前日期是周几(0-6) 0表示周日
. . .
getTime()
返回当前目期对象的时间戳, 时间戳:自1970年1月1日0时0分0秒到当前时间所经历的毫秒数计算机底层存储时间时,使用都是时间戳
Date.now()
获取当前的时间戳
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
/*
getFullYear()获取4位年份
getMonth()返当前日期的月份(0-11)
getDate()返回当前是几日
getDay()返回当前日期是周几(0-6) 0表示周日
getTime()返回当前目期对象的时间戳, 时间戳:自1970年1月1日0时0分0秒到当前时间所经历的毫秒数计算机底层存储时间时,使用都是时间戳
Date.now()获取当前的时间戳
*/
//直接通过new Date()创建时间对象时,它创建的是当前的时间的对象
let d = new Date();
//可以在Date()的构造函数中,传递一个表示时间的字符串
//字符串的格式:月/日/年 时:分:秒
//年-月-日T时:分:秒
let date = new Date("2019-12-23T23:23:22");
//new Date(年份,月,日,时,分,秒,亳秒)
let dd = new Date(2016,0,1,13,45,33);
console.log(d);
console.log(date);
console.log(dd);
</script>
</head>
<body>
</body>
</html>
2) 日期的格式化
toLocaleDateString()
//将日期转换为本地的字符串
参数
● 描述语言和国家信息的字符串
○zh-CN
中国大陆
○zh-HK
中国香港
○en-US
英国美国
● 需要一个对象作为参数,在对象中可以通过对象的属性来对日期的格式进行配置
○datestyle
日期的风格
○timestyle
时间的风格
full
long
medium
short
○hour12
是否采用12小时值
true
false
○weekday
星期的显示方式
long
short
narrow
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
/*
toLocaleDateString()//将日期转换为本地的字符串
参数
● 描述语言和国家信息的字符串
○ zh-CN 中国大陆
○ zh-HK 中国香港
○ en-US 英国美国
● 需要一个对象作为参数,在对象中可以通过对象的属性来对日期的格式进行配置
○ datestyle 日期的风格
○ timestyle 时间的风格
full
long
medium
short
hour12 是否采用12小时值
true
false
weekday 星期的显示方式
long
short
narrow
*/
let date = new Date();
console.log(date.toLocaleDateString());
</script>
</head>
<body>
</body>
</html>
⑻ 内嵌对象—包装类
在JS中,除了直接创建原始值外,也可以创建原始值的对象
通过 new String()可以创建String类型的对象
通过 new Number()可以创建Number类型的对象
通过 new Boolean()可以创建Boolean类型的对象
. . .
但是千万不要这么做
包装类:
JS中一共有5个包装类:
String
==>
字符串包装为String
对象
Number
==>
数值包装为Number
对象
Boolean
==>
布尔值包装为Boolean
对象
BigInt
==>
大整数包装为BigInt
对象
Symbol
==>
符号包装为Symbol
对象
通过包装类可以将一个原始值包装为一个对象,当我们对一个原始值调用方法或属性时,JS解释器会
临时
将原始值包装为对应的对象然后调用这个对象的属性或方法。由于原始值会被临时转换为对应的对象,这就意味着对象中的方法都可以直接通过原始值来调用
⑼ 字符串中的属性和方法
1)字符串中的属性
str.length
获取字符串的长度
str[索引]
获取指定位置的字符
str.at()
(实验方法)
根据索引获取字符,可以接受负索引
str.charAt()
根据索引获取字符
str.concat()
用来连接两个或多个字符串
str.includes()
用来检查字符串中是否包含某个内容
有返回true
没有返回false
str.indexOf()
str.lastIndex0f()
查询字符串中是否包含某个内容
有返回该内容的索引
没有返回-1
str.startsWith()
检查一个字符串是否以指定内容开头
str.endsWith()
检查一个字符串是否以指定内容结尾
Strings.padStart()
Strings.padEnd()
通过添加指定的内容,使字符串保持某个长度
str.replace()
使用一个新字符串替换一个指定内容
str.replaceAll()
使用一个新字符串替换所有指定内容
str.slice()
对字符串进行切片
str.substring()
截取字符串
str.split()
用来将一个字符串拆分为一个数组
str.toLowerCase()
将字符串转换为小写
str.toUpperCase()
将字符串转换为大写
str.trim()
去除前后空格
str.trimStart()
去除开始空格
str.trimEnd()
去除结束空格
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
let str = "张三";
console.log(str.length);
console.log(str[1]);
console.log(str.at(1));
console.log(str.at(-2));
console.log(str.charAt(0));
let str1 = "孙悟空";
let str2 = "紫霞仙子";
console.log(str1.concat(str2));
let str3 = "adb李四¥发啊发";
console.log(str3.includes("¥"));
console.log(str3.indexOf("发"));
console.log(str3.indexOf("拉"));
console.log(str3.lastIndexOf("发"));
console.log(str3.startsWith("ad"));
console.log(str3.endsWith("拉拉"));
console.log(str3.padStart(20,"¥"));
console.log(str3.padEnd(20,"¥"));
let str4 = "哈哈哈";
console.log(str4.replace("哈","呵"));
console.log(str4.replaceAll("哈","呵"));
let str5 = "发发afaf发发";
console.log(str5.slice(1,3));
let str6 = "就发发发啊发发发发广告";
console.log(str6.substring(5,6));
let str7 = "阿发@发官@方f@gsghsh";
console.log(str7.split("@"));
let str8 = "QDFDsdfaf";
console.log(str8.toLocaleLowerCase());
console.log(str8.toLocaleUpperCase());
let str9 = " adfsafa 总共 ";
console.log(str9.trim());
console.log(str9.trimStart());
console.log(str9.trimEnd());
</script>
</head>
<body>
</body>
</html>
⑽ 正则表达式
正则表达式用来定义一个规则,通过这个规则计算机可以检查一个字符串是否符合规则或者将字符串中符合规则的内容提取出来
正则表达式也是JS中的一个对象,所以要使用正则表达式,需要先创建正则表达式的对象
1)正则表达式中test()
方法
校验是否符合正则表达式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
let re = /a{3}/;
let result = re.test("aaa");
console.log(result)
</script>
</head>
<body>
</body>
</html>
2)正则表达式中exec()
方法
获取字符串中符合正则表达式的内容
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
let str = "abcaecadcafc";
//提取出str中符合axc格式的内容
//g表示全局匹配
let re = /a([a-z])c/ig;
let result = re.exec(str);
console.log(result);
while(result){
console.log(result[0],result[1],result[2]);
result = re.exec(str);
}
</script>
</head>
<body>
</body>
</html>
3)字符串的正则表达式
split()
可以根据正则表达式来对一个字符串进行拆分
search()
可以去搜索符合正则表达式的内容第一次在字符串中出现的位置
replace()
根据正则表达式替换字符串中的指定内容
match()
根据正则表达式去匹配字符串中符合要求的内容(可以设置g为全匹配
)
matchAll()
根据正则表达式去匹配字符串中符合要求的内容 (必须设置g全局匹配) 它返回的是一个迭代器
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
/*
split()
可以根据正则表达式来对一个字符串进行拆分
search()
可以去搜索符合正则表达式的内容第一次在字符串中出现的位置
replace()
根据正则表达式替换字符串中的指定内容
match()
根据正则表达式去匹配字符串中符合要求的内容
matchAll()
根据正则表达式去匹配字符串中符合要求的内容 (必须设置g全局匹配) 它返回的是一个迭代器
*/
let str = "a@q@faf!@";
//获取字母数组
console.log(str.split("@"));
let str2 = "猪八戒abc沙和尚adc孙悟空";
//获取中文数组
console.log(str2.split(/a[bd]c/));
let str3 = "dfgsg13833333333dfasg12888888888dsgsgg13455555555"
//获取dfasg所在的位置
console.log(str3.search("dfasg"));
//查询第一个手机号所在的位置
console.log(str3.search(/1[2-9]\d{9}/))
//用"手机号"替换字符串中所有的手机号,正则表达式后面加个g表示全匹配
let result = str3.replace(/1[2-9]\d{9}/g,"手机号");
console.log(result);
//获取所有的手机号组成的数组
console.log(str3.match(/1[2-9]\d{9}/g))
//根据正则表达式去匹配字符串中符合要求的内容 (必须设置g全局匹配) 它返回的是一个迭代器
let rs = str3.matchAll(/1[2-9]\d{9}/g);
for(let item of rs){
console.log(item);
}
//根据正则表达式去匹配字符串中符合要求的内容 (必须设置g全局匹配) 它返回的是一个迭代器
//可以给后九位分个组
let datas = str3.matchAll(/1[2-9](\d{9})/g);
for(let item of datas){
console.log(item);
}
</script>
</head>
<body>
</body>
</html>
2. 垃圾回收机制
3. DOM
⑴ 为什么需要DOM
⑵ 什么是DOM
<!DOCTYPE html>
<html lang="zh">
<head>
<title>My Title</title>
</head>
<body>
<h1>A Heading</h1>
<a href="#">Link Text</a>
</body>
</html>
⑶ DOM的相相关概念
1) 节点(Node)
2) 关系
⑷ 如何使用DOM
面向对象的编程语言,无非就是两个步骤:
- 找对象。
- 搞对象。
所以使用DOM我们首先要先拿到一个DOM对象,然后以该对象为切入点来完成各种操作。
要使用DOM来操作网页,我们需要浏览器至少得先给我一个对象才能去完成各种操作
所以浏览器已经为我们提供了一个document对象,它是一个全局变量可以直接使用document代表的是整个的网页
<!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>
<button id = "btn">点我一下</button>
<script>
/*
要使用DOM来操作网页,我们需要浏览器至少得先给我一个对象才能去完成各种操作
所以浏览器已经为我们提供了一个document对象,它是一个全局变量可以直接使用document代表的是整个的网页
*/
console.log(document);
//获取button标签,并修改button中的文字
//获取button对象
const btn = document.getElementById("btn");
console.log(btn);
//修改button中的内容
btn.innerText = "Click Me";
</script>
</body>
</html>
⑸ Document对象
document对象的原型链
HTMLDocument
==>
Document
==>
Node
==>
EventTarget
==>
0bject.prototype
==>
null
<!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>
<button id = "btn">点我一下</button>
<a href="#"></a>
<script>
/* document对象
- document对象表示的是整个网页
- document对象的原型链
HTMLDocument ->Document ->Node ->EventTarget -> 0bject.prototype -> null
- 凡是在原型链上存在的对象的属性和方法都可以通过Document去调用
- 部分属性:
document.documentElement ==> html根元素
document.head ==> head元素
document.title ==> title元素
document.body ==> body元素
document.links ==> 获取页面中所有的超链接
*/
console.log(document.documentElement);
console.log(document.head);
console.log(document.title);
console.log(document.body);
console.log(document.links);
</script>
</body>
</html>
⑹ 获取元素节点Element
对象
<!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>
<button id = "btn">点我一下</button>
<a href="#"></a>
<span class="span">span</span>
<span class="span">span</span>
<span class="span">span</span>
<span class="span">span</span>
<form action="#" method="post">
<label for="interests">选择您的兴趣:</label>
<br>
<input type="checkbox" id="sports" name="interests" value="sports">
<label for="sports">运动</label><br>
<input type="checkbox" id="music" name="interests" value="music">
<label for="music">音乐</label><br>
<input type="checkbox" id="books" name="interests" value="books">
<label for="books">书籍</label><br>
<input type="checkbox" id="movies" name="interests" value="movies">
<label for="movies">电影</label><br>
<input type="submit" value="提交">
</form>
<script>
/*
● document.documentElement
获取html根元素
● document.body
获取body元素
● document.getElementByID()
根据id获取一个元素节点对象
● document.getElementsByClassName()
根据class属性获取一组元素节点对象(实时更新列表)
返回的是一个类数组对象
实时更新:
该方法返回的结果是一个实时更新的集合,当网页中新添加元素时,集合也会实时的刷新
● document.getElementsByTagName()
根据标签名获取一组元素节点对象(实时更新列表)
document.getElementsByTagName("*") 可以获取页面中所有的元素
● document.getElementsByName()
根据name属性获取一组元素节点对象(实时更新列表)
主要用于表单
● document.querySelector()
根据选择器获取一个元素
● document.querySelectorAll()
根据选择器获取一组元素,该组元素类似于数组,但数组中的一些属性无法使用
*/
/*
● document.documentElement
获取html根元素
*/
console.log(document.documentElement);
/*
● document.body
获取body元素
*/
console.log(document.body);
/*
● document.getElementByID()
根据id获取一个元素节点对象
*/
console.log(document.getElementById("btn"));
/*
● document.getElementsByClassName()
根据class属性获取一组元素节点对象(实时更新列表)
返回的是一个类数组对象
实时更新:
该方法返回的结果是一个实时更新的集合,当网页中新添加元素时,集合也会实时的刷新
*/
console.log(document.getElementsByClassName("span"));
/*
● document.getElementsByTagName()
根据标签名获取一组元素节点对象(实时更新列表)
document.getElementsByTagName("*") 可以获取页面中所有的元素
*/
console.log(document.getElementsByTagName("button"));
console.log(document.getElementsByTagName("*"));
/*
● document.getElementsByName()
根据name属性获取一组元素节点对象(实时更新列表)
主要用于表单
*/
console.log(document.getElementsByName("interests"));
/*
● document.querySelector()
根据选择器获取一个元素
*/
console.log(document.querySelector(".span"));
/*
● document.querySelectorAll()
根据选择器获取一组元素,该组元素类似于数组,但数组中的一些属性无法使用
*/
console.log(document.querySelectorAll(".span"));
</script>
</body>
</html>
通过其他元素获取已有的Element对象:
div元素的原型链
HTMLDivElement
==>
HTMLElement
==>
Element
==>
Node
==>
EventTarget
==>
0bject.prototype
==>
null
通过元素节点对象获取其他节点的方法
● element.childNodes
获取当前元素的子节点(会包含空白的子节点)
● element.children
获取当前元素的子元素
● element.firstElementChild
获取当前元素的第一个子元素
● element.lastElementChild
获取当前元素的最后一个子元素
● element.nextElementSibling
获取当前元素的下一个兄弟元素
● element.previousElementSibling
获取当前元素的前一个兄弟元素
● element.parentNode
获取当前元素的父节点
● relement.tagName
获取当前元素的标签名
<!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>
<span id="hhh"></span>
<div id="box1">
我是box1
<span class="s1">
<span>我是s1</span>
</span>
<span class="s1">我是s1</span>
<div></div>
</div>
<span class="s1">我是s1</span>
<script>
/*
● element.childNodes 获取当前元素的子节点(会包含空白的子节点)
● element.children 获取当前元素的子元素(不包含空白的子节点)
● element.firstElementChild 获取当前元素的第一个子元素
● element.lastElementChild 获取当前元素的最后一个子元素
● element.nextElementSibling 获取当前元素的下一个兄弟元素
● element.previousElementSibling 获取当前元素的前一个兄弟元素
● element.parentNode 获取当前元素的父节点
● element.tagName 获取当前元素的标签名
*/
//获取div元素节点
const box1 = document.getElementById("box1");
//通过box1节点获取其他节点(只能获取box1的后代节点)
console.log(box1.getElementsByTagName("span"));
//element.childNodes 获取当前元素的子节点(会包含空白的子节点)
console.log(box1.childNodes);
//element.children 获取当前元素的子元素(不包含空白的子节点)
console.log(box1.children);
//element.firstElementChild 获取当前元素的第一个子元素
console.log(box1.firstElementChild);
//element.lastElementChild 获取当前元素的最后一个子元素
console.log(box1.lastElementChild);
//获取当前元素的下一个兄弟元素
console.log(box1.previousElementSibling);
//element.parentNode 获取当前元素的父节点
console.log(box1.parentNode);
//relement.tagName 获取当前元素的标签名
console.log(box1.tagName);
</script>
</body>
</html>
创建Element对象:
● document.createElement()
根据标签名创建元素节点对象
⑺ 网页中的文本节点对象Text
在DOM中,网页中所有的文本内容都是文本节点对象(Text),可以通过获取文本对象然后完成对它的各种操作,但这种做法会使得事情变得复杂,并不建议这么做。在大部分场景下,可以通过元素的属性来操作其中的文本内容,修改文本的三个属性
● element.textContent
获取或修改元素中的文本内容
获取的是标签中的内容,不会考虑css样式
● element.innerText
获取或修改元素中的文本内容
innerText获取内容时,会考虑css样式
通过innerText去读取CSS样式,会触发网页的重排(计算CSS样式)
当字符串中有标签时,会自动对标签进行转义
<li>
==>
glt;ligt;
● element.innerHTML
获取或修改元素中的html代码
可以直接向元素中添加html代码
innerHTML插入内容时,有被xss注入的风险
<!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>
<div id="box">
<span style="text-transform: uppercase;"><li>我是span</li></span>
</div>
<script>
/*
● element.textContent获取或修改元素中的文本内容
获取的是标签中的内容,不会考虑css样式
● element.innerText 获取或修改元素中的文本内容
innerText获取内容时,会考虑css样式
通过innerText去读取CSS样式,会触发网页的重排(计算CSS样式)
当字符串中有标签时,会自动对标签进行转义
<li> ==> glt;ligt;
● element.innerHTML 获取或修改元素中的html代码
可以直接向元素中添加html代码
innerHTML插入内容时,有被xss注入的风险
*/
const box = document.getElementById("box");
/*
lement.textContent获取或修改元素中的文本内容
获取的是标签中的内容,不会考虑css样式
*/
console.log(box.textContent);
/*
element.innerText 获取或修改元素中的文本内容
innerText获取内容时,会考虑css样式
通过innerText去读取CSS样式,会触发网页的重排(计算CSS样式)
当字符串中有标签时,会自动对标签进行转义
<li> ==> glt;ligt;
*/
console.log(box.innerText);
/*
element.innerHTML 获取或修改元素中的html代码
可以直接向元素中添加html代码
innerHTML插入内容时,有被xss注入的风险
*/
console.log(box.innerHTML);
</script>
</body>
</html>
⑻ 属性节点(Attr
)
在DOM也是一个对象,通常不需要获取对象而是直接通过元素即可完成对其的各种操作
如何操作属性节点:
① 方式一:
● 读取:元素.属性名
(注意,class属性需要使用className来读取)
读取一个布尔值时,会返回true或false
● 修改:元素.属性名=属性值
② 方式二:
● 读取:元素.getAttribute(属性名)
● 修改:元素.setAttribute(属性名,属性值)
● 删除:元素.removeAttribute(属性名)
<!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>
<div id="box">
<input disabled name="userName" value="哈哈哈" type="text"></input>
</div>
<input id="inputId" disabled="disabled" name="userName" type="text" value="呵呵呵"></input>
<script>
/*
① 方式一:
● 读取:元素.属性名(注意,class属性需要使用className来读取)
读取一个布尔值时,会返回true或false
● 修改:元素.属性名=属性值
② 方式二:
● 读取:元素.getAttribute(属性名)
● 修改:元素.setAttribute(属性名,属性值)
● 删除:元素.removeAttribute(属性名)
*/
const input = document.querySelector("[name=userName]");
/*
① 方式一:
● 读取:元素.属性名(注意,class属性需要使用className来读取)
读取一个布尔值时,会返回true或false
● 修改:元素.属性名=属性值
*/
console.log(input.type);
console.log(input.disabled);
input.value = "请输入姓名";
input.disabled = false;
/*
② 方式二:
● 读取:元素.getAttribute(属性名)
● 修改:元素.setAttribute(属性名,属性值)
● 删除:元素.removeAttribute(属性名)
*/
const element = document.getElementById("inputId");
console.log(element.getAttribute("type"));
console.log(element.getAttribute("disabled"));
//element.setAttribute("disabled",false);
element.removeAttribute("disabled");
element.setAttribute("value","设置value的值");
</script>
</body>
</html>
⑼ 事件(event)提前介绍
<!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>
<!--直接在元素的属性上设置-->
<button onclick="alert('点击了一下')">点我一下</button>
<button id="btn">再点我一下</button>
<button id="Bt">请再点我一下</button>
<script>
//可以通过为元素的指定属性设置回调函数的形式来绑定事件(一个事件只能绑定一个响应函数)
//获取按钮对象
const button = document.getElementById("btn");
button.ondblclick = function(){
alert("再点我一下~");
}
//获取按钮对象
const Bt = document.getElementById("Bt");
//可以通过元素addEventListener()方法来绑定事件
Bt.addEventListener("click",function(){
alert("通过监听绑定的点击事件1~");
});
Bt.addEventListener("click",function(){
alert("通过监听绑定的点击事件2~");
});
Bt.addEventListener("click",function(){
alert("通过监听绑定的点击事件3~");
});
</script>
</body>
</html>
⑽ 网页文档的加载
网页是自上向下加载的,如果将js代码编写到网页的上边,js代码在执行时,网页还没有加载完毕,这时会出现无法获取到D0M对象的情况
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
const btn = document.getElementById("btn");
alert(btn);
</script>
</head>
<body>
<button id="btn">点我一下</button>
</body>
</html>
无法拿到button对象
window.onload
事件会在窗口中的内容加载完毕之后才触发
document
的DOMContentLoaded
事件会在当前文档加载完毕之后触发
解决js代码无法获取到DOM对象的方法:
- 将script标签编写到body的最后
- 将代码编写到
window.onload
的回调函数中 - 将代码编写到document对象的
DOMContentLoaded
的同调函数中(执行时机更早) - 将代码编写到外部的js文件中,然后以defer的形式进行引入(执行时机更早,早于D0MContentLoaded)。
1)将script标签编写到body的最后
<!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>
<button id="btn">点我一下</button>
<script>
const btn = document.getElementById("btn");
alert(btn);
</script>
</body>
</html>
2)将代码编写到window.onload
的回调函数中
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
window.onload = function(){
const btn = document.getElementById("btn");
alert(btn);
}
</script>
</head>
<body>
<button id="btn">点我一下</button>
</body>
</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>
<script>
window.addEventListener("load",function(){
const btn = document.getElementById("btn");
alert(btn);
})
</script>
</head>
<body>
<button id="btn">点我一下</button>
</body>
</html>
3)将代码编写到document对象的DOMContentLoaded
的同调函数中(执行时机更早)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
window.addEventListener("DOMContentLoaded",function(){
const btn = document.getElementById("btn");
alert(btn);
})
</script>
</head>
<body>
<button id="btn">点我一下</button>
</body>
</html>
4)将代码编写到外部的js文件中,然后以defer的形式进行引入(执行时机更早,早于D0MContentLoaded)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
window.addEventListener("DOMContentLoaded",function(){
const btn = document.getElementById("btn");
alert("DOMContentLoaded中的"+btn);
})
</script>
<script defer src="./js/script.js"></script>
</head>
<body>
<button id="btn">点我一下</button>
</body>
</html>
const btn = document.getElementById("btn");
alert("外部js获取的"+btn);
⑾ DOM中元素的修改
1) DOM元素中插入新的元素
● 元素.appendChild
用于给一个节点添加子节点
<!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>
<button id="btn">按钮</button>
<hr/>
<ul id="list">
<li id="swk">孙悟空</li>
<li id="ts">唐僧</li>
<li id="zbj">猪八戒</li>
</ul>
<script>
//点击按钮,向ul列表中添加一个白龙马
//获取ul标签
const list = document.getElementById("list");
//获取按钮
const btn = document.getElementById("btn");
btn.onclick = function(){
//创建一个li标签
const li = document.createElement("li");
//向li标签中添加文本
li.textContent = "白龙马";
//给li添加id属性
li.id = "blm";
console.log(li);
//将创建好的li标签添加到ul标签里
//appendChild 用于给一个节点添加子节点
list.appendChild(li);
}
</script>
</body>
</html>
● 元素.insertAdjacentElement(位置参数,节点)
可以向元素的任意位置添加元素
位置参数值:
○ beforeend 标签的最后添加子节点
○ afterbegin 标签的开始添加子节点
○ afterend 在元素后面插入元素(兄弟元素)
○ beforebegin 在元素前面插入元素(兄弟元素)
<!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>
<button id="btn">按钮</button>
<hr/>
<ul id="list">
<li id="swk">孙悟空</li>
<li id="ts">唐僧</li>
<li id="zbj">猪八戒</li>
</ul>
<script>
//点击按钮,向ul列表中添加一个白龙马
//获取ul标签
const list = document.getElementById("list");
//获取按钮
const btn = document.getElementById("btn");
btn.onclick = function(){
//创建一个li标签
const li = document.createElement("li");
//向li标签中添加文本
li.textContent = "白龙马";
//给li添加id属性
li.id = "blm";
console.log(li);
//将创建好的li标签添加到ul标签里
/*
insertAdjacentElement(添加的位置,添加的元素)
可以向元素的任意位置添加元素
添加的位置参数:
● beforeend 标签的最后添加子节点
● afterbegin 标签的开始添加子节点
● afterend 在元素后面插入元素(兄弟元素)
● beforebegin 在元素前面插入元素(兄弟元素)
*/
list.insertAdjacentElement("beforeend",li);
}
</script>
</body>
</html>
● 元素.insertAdjacentHTML(位置参数,html代码)
可以向元素的任意位置添加html文本
位置参数值:
○ beforeend 标签的最后添加子节点
○ afterbegin 标签的开始添加子节点
○ afterend 在元素后面插入元素(兄弟元素)
○ beforebegin 在元素前面插入元素(兄弟元素)
<!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>
<button id="btn">按钮</button>
<hr/>
<ul id="list">
<li id="swk">孙悟空</li>
<li id="ts">唐僧</li>
<li id="zbj">猪八戒</li>
</ul>
<script>
//点击按钮,向ul列表中添加一个白龙马
//获取ul标签
const list = document.getElementById("list");
//获取按钮
const btn = document.getElementById("btn");
btn.onclick = function(){
/*
元素.insertAdjacentHTML(位置参数,html代码) 可以向元素的任意位置添加html文本
位置参数值:
○ beforeend 标签的最后添加子节点
○ afterbegin 标签的开始添加子节点
○ afterend 在元素后面插入元素(兄弟元素)
○ beforebegin 在元素前面插入元素(兄弟元素)
*/
list.insertAdjacentHTML("beforeend","<li id='blm'>白龙马</li>");
}
</script>
</body>
</html>
2) DOM中元素的替换
● 元素1.replaceWith(元素2)
用元素2去替换元素1
<!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>
<button id="btn">按钮</button>
<hr/>
<ul id="list">
<li id="swk">孙悟空</li>
<li id="ts">唐僧</li>
<li id="zbj">猪八戒</li>
</ul>
<script>
//点击按钮,替换ul列表中的孙悟空
//获取按钮
const btn = document.getElementById("btn");
btn.onclick = function(){
//创建一个li标签
const li = document.createElement("li");
//向li标签中添加文本
li.textContent = "白龙马";
//给li添加id属性
li.id = "blm";
console.log(li);
//获取孙悟空的li标签
const swk = document.getElementById("swk");
//替换孙悟空的li标签
swk.replaceWith(li);
}
</script>
</body>
</html>
3) DOM中元素的删除
● 元素.remove()
删除元素
<!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>
<button id="btn">按钮</button>
<hr/>
<ul id="list">
<li id="swk">孙悟空</li>
<li id="ts">唐僧</li>
<li id="zbj">猪八戒</li>
</ul>
<script>
//点击按钮,删除ul列表中的孙悟空
//获取按钮
const btn = document.getElementById("btn");
btn.onclick = function(){
//获取id为swk的li
const swk = document.getElementById("swk");
swk.remove();
}
</script>
</body>
</html>
⑿ 节点的复制
● cloneNode()
方法对节点进行复制时,它会复制节点的所有特点包括各种属性。这个方法默认只会复制当前节点,而不会复制节点的子节点。可以传递一个true作为参数,这样该方法也会将元素的子节点一起复制
<!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>
<button id="btn">按钮</button>
<hr/>
<ul id="list">
<li id="swk">孙悟空</li>
<li id="ts">唐僧</li>
<li id="zbj">猪八戒</li>
</ul>
<ul id="list2">
<li>蜘蛛精</li>
</ul>
<script>
//点击按钮,将孙悟空复制到list2中
//获取id为swk的li
const swk = document.getElementById("swk");
//获取list2
const list2 = document.getElementById("list2");
//获取按钮
const btn = document.getElementById("btn");
btn.onclick = function(){
//将节点swk进行复制
const newli = swk.cloneNode(true);
list2.appendChild(newli);
}
</script>
</body>
</html>
⒀ javascript 修改css样式
通过javascript 修改css的方式:
元素.style.样式名 = 样式值
如果样式名中含有
-
,则需要将样式表修改为驼峰命名法
background-color
==>backgroundColor
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
div{
width: 200px;
height: 200px;
background-color: green;
}
</style>
</head>
<body>
<button id="btn">按钮</button>
<hr/>
<div id="dd"></div>
<script>
//点击按钮,将div长、宽改为 400px 并且将背景颜色改成红色
//获取id为dd的div
const dd = document.getElementById("dd");
//获取按钮
const btn = document.getElementById("btn");
btn.onclick = function(){
/*
通过javascript 修改css的方式:
元素.style.样式名 = 样式值
*/
dd.style.width = "400px";
dd.style.height = "400px";
dd.style.backgroundColor = "red";
}
</script>
</body>
</html>
⒁ javascript 获取 css样式
1) 通过 getComputedstyle()
获取样式
getComputedstyle()
它会返回一个对象,这个对象中包含了当前元素所有的生效的样式
● 参数:
○ 1.要获取样式的对象
○ 2.要获取的伪元素
● 返回值:
返回的一个对象,对象中存储了当前元素的样式
注意:
- 样式对象中返回的样式值,不一定能来拿来直接计算所以使用时,一定要确保值是可以计算的才去计算
- 通过
样式对象.样式名
只能获取样式,不能修改样式。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
div{
width: 200px;
height: 200px;
background-color: green;
}
</style>
</head>
<body>
<button id="btn">按钮</button>
<hr/>
<div id="dd"></div>
<script>
//点击按钮,将div长、宽改为 400px 并且将背景颜色改成红色
//获取id为dd的div
const dd = document.getElementById("dd");
//获取按钮
const btn = document.getElementById("btn");
btn.onclick = function(){
/*
getComputedstyle() 它会返回一个对象,这个对象中包含了当前元素所有的生效的样式
● 参数:
○ 1.要获取样式的对象
○ 2.要获取的伪元素
● 返回值:
返回的一个对象,对象中存储了当前元素的样式
*/
const objStyle = getComputedStyle(dd);
console.log(objStyle.width);
console.log(objStyle.height);
console.log(parseInt(objStyle.width));
console.log(objStyle.background);
dd.style.width = parseInt(objStyle.width) + 100 + "px";
dd.style.height = parseInt(objStyle.height) + 100 + "px";
dd.style.background = "yellow";
}
</script>
</body>
</html>
2)通过属性读取样式
● 获取元素内部的宽度和高度(内容区context和内边距padding)
元素.clientHeight
元素.clientWidth
● 获取元素内部的宽度和高度(内容区context、内边距padding和边框border)
元素.offsetHeight
元素.offsetWidth
● 获取元素滚动区域的大小
元素.scrollHeight
元素.scrollWidth
● 获取元素的定位父元素
元素.offsetParent
定位父元素:离当前元素最近的开启了定位的祖先元素,如果所有的元素都没有开启定位则返回body
● 获取元素相对与定位元素的偏移量
元素.offsetTop
元素.offsetLeft
● 获取或者设置元素滚动条的偏移量
元素.scrollTop
元素.scrollLeft
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
#dd{
width: 200px;
height: 200px;
padding: 50px;
margin: 50px;
border: 10px red solid;
background-color: green;
overflow: auto;
}
#dd2{
width: 100px;
height: 600px;
background-color: yellow;
}
</style>
</head>
<body>
<button id="btn">按钮</button>
<hr/>
<div id="dd" style="position: relative;">
<div id="dd2"></div>
</div>
<script>
const btn = document.getElementById("btn");
const dd = document.getElementById("dd");
btn.onclick = function(){
/*
获取元素内部的宽度和高度(内容区context和内边距padding)
元素.clientHeight
元素.clientWidth
*/
console.log(dd.clientHeight);
/*
获取元素内部的宽度和高度(内容区context、内边距padding和边框border)
元素.offsetHeight
元素.offsetWidth
*/
console.log(dd.offsetHeight);
/*
元素.scrollHeight
元素.scrollWidth
获取元素滚动区域的大小
*/
console.log(dd.scrollHeight);
/*
元素.offsetParent
获取元素的定位父元素
定位父元素:离当前元素最近的开启了定位的祖先元素,如果所有的元素都没有开启定位则返回body
*/
const dd2 = document.getElementById("dd2");
console.log(dd2.offsetParent);
/*
获取元素相对与定位元素的偏移量
元素.offsetTop
元素.offsetLeft
*/
console.log(dd2.offsetLeft);
/*
获取或者设置元素滚动条的偏移量
元素.scrollTop
元素.scrollLeft
*/
console.log(dd.scrollTop);
}
</script>
</body>
</html>
⒂ javascript 操作元素class属性
除了直接修改样式外,也可以通过修改class属性来间接的修改样式,通过class修改样式的好处:
- 可以一次性修改多个样式
- 对JS和CSS进行解耦
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.dd2{
width: 200px;
height: 200px;
padding: 50px;
margin: 50px;
border: 10px red solid;
background-color: green;
overflow: auto;
}
.dd{
width: 100px;
height: 300px;
background-color: yellow;
}
</style>
</head>
<body>
<button id="btn">按钮</button>
<hr/>
<div class="dd">
</div>
<script>
const btn = document.getElementById("btn");
const dd = document.getElementsByClassName("dd")[0];
console.log(dd);
btn.onclick = function(){
//除了直接修改样式外,也可以通过修改class属性来间接的修改样式
dd.className += " dd2";
}
</script>
</body>
</html>
-
元素.classList
是一个对象,对象中提供了对当前元素的类的各种操作方法
○元素.classList.add()
向元素中添加一个或多个class<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> .dd2{ width: 200px; height: 200px; padding: 50px; margin: 50px; border: 10px red solid; background-color: green; overflow: auto; } .dd{ width: 100px; height: 300px; background-color: yellow; } </style> </head> <body> <button id="btn">按钮</button> <hr/> <div class="dd"> </div> <script> const btn = document.getElementById("btn"); const dd = document.getElementsByClassName("dd")[0]; console.log(dd); btn.onclick = function(){ dd.classList.add("dd2"); } </script> </body> </html>
○元素.classList.remove()
移除元素中的一个或多个class<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> .dd2{ width: 200px; height: 200px; padding: 50px; margin: 50px; border: 10px red solid; background-color: green; overflow: auto; } .dd{ width: 100px; height: 300px; background-color: yellow; } </style> </head> <body> <button id="btn">按钮</button> <hr/> <div class="dd dd2"> </div> <script> const btn = document.getElementById("btn"); const dd = document.getElementsByClassName("dd")[0]; console.log(dd); btn.onclick = function(){ dd.classList.remove("dd2"); } </script> </body> </html>
○ 元素.classList.toggle()
切换元素中的class
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.dd2{
width: 200px;
height: 200px;
padding: 50px;
margin: 50px;
border: 10px red solid;
background-color: green;
overflow: auto;
}
.dd{
width: 100px;
height: 300px;
background-color: yellow;
}
</style>
</head>
<body>
<button id="btn">按钮</button>
<hr/>
<div class="dd">
</div>
<script>
const btn = document.getElementById("btn");
const dd = document.getElementsByClassName("dd")[0];
console.log(dd);
btn.onclick = function(){
dd.classList.toggle("dd2");
}
</script>
</body>
</html>
○ 元素.classList.replace()
替换class
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.dd2{
width: 200px;
height: 200px;
padding: 50px;
margin: 50px;
border: 10px red solid;
background-color: green;
overflow: auto;
}
.dd{
width: 100px;
height: 300px;
background-color: yellow;
}
</style>
</head>
<body>
<button id="btn">按钮</button>
<hr/>
<div class="dd">
</div>
<script>
const btn = document.getElementById("btn");
const dd = document.getElementsByClassName("dd")[0];
console.log(dd);
btn.onclick = function(){
dd.classList.replace("dd","dd2");
}
</script>
</body>
</html>
○ 元素.classList.contains()
检查class
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.dd2{
width: 200px;
height: 200px;
padding: 50px;
margin: 50px;
border: 10px red solid;
background-color: green;
overflow: auto;
}
.dd{
width: 100px;
height: 300px;
background-color: yellow;
}
</style>
</head>
<body>
<button id="btn">按钮</button>
<hr/>
<div class="dd">
</div>
<script>
const btn = document.getElementById("btn");
const dd = document.getElementsByClassName("dd")[0];
console.log(dd);
btn.onclick = function(){
console.log(dd.classList.contains("dd"));
}
</script>
</body>
</html>
⒃ 事件对象(Event
)
事件指用户和网页之间发生的交互行为。比如点击按钮、移动鼠标、改变窗口大小、表单输入等等,用户的所有操作都可以被当成是一个事件。JS中通过为事件绑定回调函数来处理事件,绑定回调函数后,事件触发后回调函数便会执行,以此来响应用户的行为,所以事件的回调函数我们也称其为事件的响应函数。事件对象是由浏览器在事件触发时所创建的对象。这个对象中封装了事件相关的各种信息。通过事件对象可以获取到事件的详细信息,比如:鼠标的坐标、键盘的按键。.浏览器在创建事件对象后,会将事件对象作为响应函数的参数传递,所以我们可以在事件的回调函数中定义一个形参来接收事件对象。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
#div{
width: 200px;
height: 200px;
padding: 50px;
margin: 50px;
border: 10px red solid;
background-color: green;
overflow: auto;
}
</style>
</head>
<body>
<div id="div"></div>
<script>
const div = document.getElementById("div");
//记录鼠标移动的坐标
/*div.addEventListener("mousemove",function(even){
div.textContemnt = even.clientX + "," + even.clientY;
});*/
div.addEventListener("mousemove",even=>{
console.log(even.clientX,even.clientY);
});
</script>
</body>
</html>
1) 事件Event
对象中的属性和方法
在DOM中存在着多种不同类型的事件对象,多种事件对象有一个共同的祖先Event
● event.target
触发事件的对象
● event.currentTarget
绑定事件的对象(同this)
● event.stopPropagation()
停止事件的传导(一般用于禁止事件冒泡)
● event.preventDefault()
取消默认行为
① 事件的冒泡(bubble)
事件的冒泡就是指事件的向上传导,当元素上的某个事件被触发后,其祖先元素上的相同事件也会同时被触发。 冒泡的存在大大的简化了代码的编写,但是在一些场景下我们并不希望冒泡存。在不希望事件冒泡时,可以通过事件对象来取消冒泡
● 触发事件的对象和绑定事件的对象对比
event.target
触发事件的对象
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js讲解</title>
<style>
#box1{
width: 500px;
height: 500px;
background-color: green;
}
#box2{
width: 300px;
height: 300px;
background-color: yellow;
}
#box3{
width: 200px;
height: 200px;
background-color: blue;
}
</style>
</head>
<body>
<div id="box1">
<div id="box2">
<div id="box3"></div>
</div>
</div>
<script>
const box1 = document.getElementById("box1");
const box2 = document.getElementById("box2");
const box3 = document.getElementById("box3");
//给box1添加点击事件
box1.addEventListener("click",function(even){
//event.target 触发事件的对象
console.log(even.target);
alert("box1被点击了");
});
box2.addEventListener("click",function(even){
//event.target 触发事件的对象
console.log(even.target);
alert("box2被点击了");
});
box3.addEventListener("click",function(even){
//event.target 触发事件的对象
console.log(even.target);
alert("box3被点击了");
});
</script>
</body>
</html>
因为点击box3触发的事件,所以打印的都是box3对象。
event.currentTarget
绑定事件的对象(同this)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js讲解</title>
<style>
#box1{
width: 500px;
height: 500px;
background-color: green;
}
#box2{
width: 300px;
height: 300px;
background-color: yellow;
}
#box3{
width: 200px;
height: 200px;
background-color: blue;
}
</style>
</head>
<body>
<div id="box1">
<div id="box2">
<div id="box3"></div>
</div>
</div>
<script>
const box1 = document.getElementById("box1");
const box2 = document.getElementById("box2");
const box3 = document.getElementById("box3");
//给box1添加点击事件
box1.addEventListener("click",function(even){
//event.currentTarget 绑定事件的对象(同this)
console.log(even.currentTarget);
alert("box1被点击了");
});
box2.addEventListener("click",function(even){
//event.currentTarget 绑定事件的对象(同this)
console.log(even.currentTarget)
alert("box2被点击了");
});
box3.addEventListener("click",function(even){
//event.currentTarget 绑定事件的对象(同this)
console.log(even.currentTarget)
alert("box3被点击了");
});
</script>
</body>
</html>
因为点击事件都分别绑定在box1、box2和box3上,所以分别打印box1、box2和box3对象
● 事件冒泡演示
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js讲解</title>
<style>
#box1{
width: 500px;
height: 500px;
background-color: green;
}
#box2{
width: 300px;
height: 300px;
background-color: yellow;
}
#box3{
width: 200px;
height: 200px;
background-color: blue;
}
</style>
</head>
<body>
<div id="box1">
<div id="box2">
<div id="box3"></div>
</div>
</div>
<script>
const box1 = document.getElementById("box1");
const box2 = document.getElementById("box2");
const box3 = document.getElementById("box3");
//给box1添加点击事件
box1.addEventListener("click",even=>{
alert("box1被点击了");
});
box2.addEventListener("click",function(even){
alert("box2被点击了");
});
box3.addEventListener("click",function(even){
alert("box3被点击了");
});
</script>
</body>
</html>
点击box3,box2和box1绑定的事件也被出发。
事件的冒泡和元素样式无关,只跟元素的结构有关
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js讲解</title>
<style>
#box1{
width: 200px;
height: 200px;
background-color: yellow;
}
#box2{
width: 100px;
height: 100px;
background-color: rebeccapurple;
position: absolute;
bottom: 0;
}
</style>
</head>
<body>
<div id="box1" onclick="alert('1')">
<div id="box2" onclick="alert('2')"></div>
</div>
</body>
</html>
虽然样式上box1没有包含box2,但是结构上box1还是包含了box2。触发box2的点击事件依然会触发box1的点击事件。说明事件的冒泡和元素样式无关,只跟元素的结构有关。
● 通过event.stopPropagation()
禁用冒泡演示
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js讲解</title>
<style>
#box1{
width: 500px;
height: 500px;
background-color: green;
}
#box2{
width: 300px;
height: 300px;
background-color: yellow;
}
#box3{
width: 200px;
height: 200px;
background-color: blue;
}
</style>
</head>
<body>
<div id="box1">
<div id="box2">
<div id="box3"></div>
</div>
</div>
<script>
const box1 = document.getElementById("box1");
const box2 = document.getElementById("box2");
const box3 = document.getElementById("box3");
//给box1添加点击事件
box1.addEventListener("click",function(even){
//通过event.stopPropagation()禁用冒泡演示
alert("box1被点击了");
});
box2.addEventListener("click",function(even){
//通过event.stopPropagation()禁用冒泡演示
even.stopPropagation();
alert("box2被点击了");
});
box3.addEventListener("click",function(even){
//通过event.stopPropagation()禁用冒泡演示
even.stopPropagation();
alert("box3被点击了");
});
</script>
</body>
</html>
点击box3,box1和box2不会被触发
● event.preventDefault()
取消默认行为
演示超链接的默认行为
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js讲解</title>
</head>
<body>
<a id="a" href="https://www.baidu.com">点我</a>
<script>
const a = document.getElementById("a");
a.addEventListener("click",function(even){
alert("点击了一下");
})
</script>
</body>
</html>
给超链接绑定的点击事件执行了,但它的默认行为也执行了。
通过event.preventDefault()
取消超链接默认行为
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js讲解</title>
</head>
<body>
<a id="a" href="https://www.baidu.com">点我</a>
<script>
const a = document.getElementById("a");
a.addEventListener("click",function(even){
even.preventDefault();
alert("点击了一下");
})
</script>
</body>
</html>
给超链接绑定的点击事件执行了,但它的默认行为没有执行。
2) 事件的委派
委派就是将本该绑定给多个元素的事件,统一绑定给document,这样可以降低代码复杂度方便维护
● 点击按钮添加超链接演示
<!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>
<button id="btn">点击添加列表</button>
<ul id="list">
<li><a href="javascript:;">链接一</a></li>
<li><a href="javascript:;">链接二</a></li>
<li><a href="javascript:;">链接三</a></li>
</ul>
<script>
//获取ul 中所有的a标签
const links = document.querySelectorAll("ul a");
const btn = document.getElementById("btn");
const list = document.getElementById("list");
//遍历超链接,并给超链接添加点击弹出超链接文本内容的点击事件
for(let i=0;i<links.length;i++){
links[i].addEventListener("click",even =>{
alert(even.target.textContent);
});
}
//点击后在ul中添加一个新的li
btn.addEventListener("click",even=>{
list.insertAdjacentHTML("beforeend","<li><a href='javascript:;'>新的超链接</a></li>");
});
</script>
</body>
</html>
点击按钮虽然能够添加新的新的超链接,但是页面刷新就已经给所有的超链接添加了点击事件,所有后添加的列表中的超链接没有添加上点击事件
上面问题的解决思路:
我们希望: 只绑定一次事件,既可以让所有的超链接,包括当前的和未来新建的超链接都具有这些事件
思路:
可以将事件统一绑定给document
,这样点击超链接时由于事件的冒泡,会导致document
上的点击事件被触发,这样只绑定一次,所有的超链接都会具有这些事件
<!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>
<button id="btn">点击添加列表</button>
<ul id="list">
<li><a href="javascript:;">链接一</a></li>
<li><a href="javascript:;">链接二</a></li>
<li><a href="javascript:;">链接三</a></li>
</ul>
<script>
//获取ul 中所有的a标签
//const links = document.querySelectorAll("ul a");
const btn = document.getElementById("btn");
const list = document.getElementById("list");
/*遍历超链接,并给超链接添加点击提出超链接文本内容的点击事件
for(let i=0;i<links.length;i++){
links[i].addEventListener("click",even =>{
alert(even.target.textContent);
});
}*/
document.addEventListener("click",even=>{
alert(even.target.textContent);
});
//点击后在ul中添加一个新的li
btn.addEventListener("click",even=>{
list.insertAdjacentHTML("beforeend","<li><a href='javascript:;'>新的超链接</a></li>");
});
</script>
</body>
</html>
虽然实现了点击新加的超链接也能弹出超链接的内容,但是鼠标点击哪里都会弹出其中的文本内容,显示这样是不合理的
● 上诉问题可以通过判断条件让只有点击标签a的超链接才能触发弹窗事件
<!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>
<button id="btn">点击添加列表</button>
<ul id="list">
<li><a href="javascript:;">链接一</a></li>
<li><a href="javascript:;">链接二</a></li>
<li><a href="javascript:;">链接三</a></li>
</ul>
<script>
const btn = document.getElementById("btn");
const list = document.getElementById("list");
//获取list中的所有超链接
const links = list.getElementsByTagName("a");
document.addEventListener("click",even=>{
//在执行代码前先判断一下事件是谁触发的
/*
因为通过元素.getElementsByTagName()获取到的“集合”是伪数组
所以要先转换为数组才能使用数组中的方法
*/
//方式一:通过Array.from()方式转换成数组
//const arr = Array.from(liks);
//方式二:通过展开的方式转换成数组
const arr = [...links];
//检查even.target是否在links中存在
if(arr.includes(event.target)){
alert(even.target.textContent);
}
});
//点击后在ul中添加一个新的li
btn.addEventListener("click",even=>{
list.insertAdjacentHTML("beforeend","<li><a href='javascript:;'>新的超链接</a></li>");
});
</script>
</body>
</html>
成功解决上诉问题
3) 事件的捕获
事件的传播机制:
在DOM中,事件的传播可以分为三个阶段:
1.捕获阶段(由祖先元素向目标元素进行事件的捕获)(默认情况下,事件不会在捕获阶段触发)
2.目标阶段(触发事件的对象)
3.冒泡阶段(由目标元素向祖先元素进行事件的冒泡)
事件的捕获,指事件从外向内的传导
当前元素触发事件以后,会先从当前元素最大的祖先元素开始向当前元素进行事件的捕获
如果希望在捕获阶段触发事件,可以将addEventListener
的第三个参数设置为true
。般情况下我们不希望事件在捕获阶段触发,所有通常都不需要设置第三个参数
even.eventPhase
获取事件触发的阶段
1 捕获阶段 2 目标阶段 3 冒泡阶段
● 默认事件触发情况演示
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
#box1{
width: 300px;
height: 300px;
background-color: red;
}
#box2{
width: 200px;
height: 200px;
background-color: yellow;
}
#box3{
width: 100px;
height: 100px;
background-color: green;
}
</style>
</head>
<body>
<div id="box1">
<div id="box2">
<div id="box3">
</div>
</div>
</div>
<script>
const box1 = document.getElementById("box1");
const box2 = document.getElementById("box2");
const box3 = document.getElementById("box3");
box1.addEventListener("click",even=>{
//eventPhase 表示事件触发的阶段,1 捕获阶段 2 目标阶段 3 冒泡阶段
alert("1"+even.eventPhase);
});
box2.addEventListener("click",even=>{
//eventPhase 表示事件触发的阶段,1 捕获阶段 2 目标阶段 3 冒泡阶段
alert("2"+even.eventPhase);
});
box3.addEventListener("click",even=>{
//eventPhase 表示事件触发的阶段,1 捕获阶段 2 目标阶段 3 冒泡阶段
alert("3"+even.eventPhase);
});
</script>
</body>
</html>
由图可知,元素从目标元素开始执行事件,最后执行的是祖先的元素。并且由even.eventPhase
可知box3点击事件在目标阶段执行,box2在冒泡阶段执行,box1在冒泡阶段执行
● 开启捕获阶段触发事件情况演示
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
#box1{
width: 300px;
height: 300px;
background-color: red;
}
#box2{
width: 200px;
height: 200px;
background-color: yellow;
}
#box3{
width: 100px;
height: 100px;
background-color: green;
}
</style>
</head>
<body>
<div id="box1">
<div id="box2">
<div id="box3">
</div>
</div>
</div>
<script>
const box1 = document.getElementById("box1");
const box2 = document.getElementById("box2");
const box3 = document.getElementById("box3");
box1.addEventListener("click",even=>{
//eventPhase 表示事件触发的阶段,1 捕获阶段 2 目标阶段 3 冒泡阶段
alert("1"+even.eventPhase);
},true);
box2.addEventListener("click",even=>{
//eventPhase 表示事件触发的阶段,1 捕获阶段 2 目标阶段 3 冒泡阶段
alert("2"+even.eventPhase);
},true);
box3.addEventListener("click",even=>{
//eventPhase 表示事件触发的阶段,1 捕获阶段 2 目标阶段 3 冒泡阶段
alert("3"+even.eventPhase);
},true);
</script>
</body>
</html>
由图可知,元素从祖先元素开始执行事件,最后执行的是目标的元素。并且由even.eventPhase
可知box1点击事件在捕获阶段,box2点击事件在捕获阶段,box3在目标阶段执行
4. BOM(Browser Object Model) 浏览器对象模型
浏览器对象模型,BOM
为我们提供了一组对象,通过这组对象可以完成对浏览器的各种操作。BOM对象
:
● Window
代表浏览器窗口(全局对象)
● Navigator
浏览器的对象(可以用来识别浏览器)
● Location
浏览器的地址栏信息
● History
浏览器的历史记录(控制浏览器前进后退)
● Screen
屏幕的信息
BOM
对象都是作为window对象的属性保存的,所以可以直接在JS中访问这些对象
⑴ Navigator
浏览器的对象(可以用来识别浏览器)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
var sBrowser, sUsrAg = navigator.userAgent;
// The order matters here, and this may report false positives for unlisted browsers.
if (sUsrAg.indexOf("Firefox") > -1) {
sBrowser = "Mozilla Firefox";
} else if (sUsrAg.indexOf("Opera") > -1 || sUsrAg.indexOf("OPR") > -1) {
sBrowser = "Opera";
} else if (sUsrAg.indexOf("Trident") > -1) {
sBrowser = "Microsoft Internet Explorer";
} else if (sUsrAg.indexOf("Edge") > -1) {
sBrowser = "Microsoft Edge";
} else if (sUsrAg.indexOf("Chrome") > -1) {
sBrowser = "Google Chrome or Chromium";
} else if (sUsrAg.indexOf("Safari") > -1) {
sBrowser = "Apple Safari";
} else {
sBrowser = "unknown";
}
alert("当前浏览器为: " + sBrowser);
</script>
</head>
<body>
</html>
⑵ Location
浏览器的地址栏信息
location 表示的是浏览器地址栏的信息
● 可以直接将location的值修改为一个新的地址,这样会使得网页发生跳转
● location.assign()
跳转到一个新的地址
● location.replace()
跳转到一个新的地址(无法通过回退按钮回退)
● location.reload()
刷新页面,可以传递一个true来强制清缓存刷新
● location.href
获取当前地址
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<button id="btn">点击跳转</button>
<script>
const btn = document.getElementById("btn");
/*
● 可以直接将location的值修改为一个新的地址,这样会使得网页发生跳转
● location.assign()跳转到一个新的地址
● location.replace()跳转到一个新的地址(无法通过回退按钮回退)
● location.reload()刷新页面,可以传递一个true来强制清缓存刷新
● location.href 获取当前地址
*/
btn.addEventListener("click",()=>{
//location = "https://www.baidu.com";
//location.assign("https://www.baidu.com");
//location.replace("https://www.baidu.com");
//location.reload(true);
console.log(location.href);
});
</script>
</head>
<body>
</html>
⑶ History
浏览器的历史记录(控制浏览器前进后退)
● history.back()
回退按钮
● history.forward()
前进按钮
● history.go()
可以向前跳转也可以向后跳转,正值向前跳转,负值向后跳转
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<button id="btn">点击跳转</button>
<script>
const btn = document.getElementById("btn");
/*
● history.back()回退按钮
● history.forward()前进按钮
● history.go()可以向前跳转也可以向后跳转,正值向前跳转,负值向后跳转
*/
btn.addEventListener("click",()=>{
history.back();
//history.forward();
//history.go(-1);
});
</script>
</head>
<body>
</html>
5. 定时器
通过定时器,可以使代码在指定时间后执行-设置定时器的方式有两种:
● setTimeout()
定时器
○ setTimeout()
设置多少时间后代码执行,只会执行一次
参数:
1.回调函数(要执行的代码)
2.间隔的时间(毫秒)
○ clearTimeout()
关闭定时器
● setInterval()
定时器
○ setInterval()
设置定时器(每间隔一段时间代码就会执行一次)
参数:
1.回调函数(要执行的代码)
2.间隔的时间(亳秒)
○ clearInterval()
关闭定时器
⑴ setTimeout()
定时器 案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
setTimeout(()=>{
alert("执行了~");
},3000);
</script>
</head>
<body>
</html>
函数三秒后执行了
⑵ setInterval()
定时器 案例
<!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>
<h1 id="num"></h1>
<script>
const numH1 = document.getElementById("num");
let num = 0;
//设置定时器每隔0.1秒执行一次
const timer = setInterval(()=>{
num++;
numH1.textContent = num;
if(num === 30){
//如果num等于30,关闭定时器
clearInterval(timer);
}
},100);
</script>
</html>
6. 调用栈(call stack
)的介绍
7. 消息队列的介绍
三、jQuery介绍
1. 什么是jQuery
2. jQuery的缺点 —— 一个过时的库
3. 引入JQuery
⑴ 使用公共cdn比较简单,以字节跳动静态资源为例,要引入3.x版本的jQuery,只需要将如下代码粘贴到网页中即可:
<script src="https://lf9-cdn-tos.bytecdntp.com/cdn/expire-1-M/jquery/3.6.0/jquery.js"></script>
或者
<script src="https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/jquery/3.6.0/jquery.min.js"></script>
完整版代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- <script src="https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/jquery/3.6.0/jquery.min.js"></script> -->
<script src="https://lf9-cdn-tos.bytecdntp.com/cdn/expire-1-M/jquery/3.6.0/jquery.js"></script>
</head>
<body>
<script>
console.log($);
</script>
</html>
⑵ 本地引入:
下载地址:
开发环境版:https://code.jquery.com/jquery-3.6.1.js
生产环境版:https://code.jquery.com/jquery-3.6.1.min.js
完整代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./js/jquery-3.6.1.min.js"></script>
</head>
<body>
<script>
console.log($);
</script>
</html>
4. JQuery核心函数
● jQuery.contains()
● jQuery.isArray()
● jQuery.isFunction()
● jQuery.isNumeric()
● ……
另一种是将其作为函数调用,根据参数的不同可以会发挥不同的作用。
● jQuery(函数)
● jQuery(选择器)
● jQuery(DOM对象)
● jQuery(HTML代码)
注意:上述编写代码时可以使用
$
代替jQuery。
⑴ jQuery核心函数的功能两种作用
1) 将它作为工具类使用
在核心函数中jQuery为我们提供了多个工具方法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./js/jquery-3.6.1.min.js"></script>
</head>
<body>
<script>
var a = 111;
const fn = function(){};
//$.isFunction()判断参数是不是方法
console.log($.isFunction(a));
console.log($.isFunction(fn));
</script>
</html>
2) 将它作为函数使用
① 将一个函数
作为$
的参数
这个函数会在文档加载完毕之后执行
相当于:
document.addEventListener("DOMContentLoaded", function(){})
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./js/jquery-3.6.1.min.js"></script>
</head>
<body>
<script>
alert("原生alert~");
jQuery(alert("jQuery修改后的alert~"));
</script>
</html>
② 将选择器字符串作为参数
jQuery
自动去网页中查找元素
作用类似于
document.querySelectorAll("...")
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./js/jquery-3.6.1.min.js"></script>
</head>
<body>
<button id="btn">按钮</button>
<script>
const btn = document.getElementById("btn");
alert(btn);
alert($("#btn"));
</script>
</html>
注意:
通过jQuery核心函数查询到的结果并不是原生的DOM对象,而是一个经过jQuery包装过的新的对象,这个对象我们称其为jQuery对象。jQuery对象中为我们提供了很多新的方法,方便我们做各种DOM操作。但是jQuery对象不能直接调用原生DOM对象的方法。通常我们为jQuery对象命名时,会使用$
开头,加以区分
③ 将DOM对象作为参数
可以将DOM对象转换为jQuery对象,从而使用jQuery对象的方法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./js/jquery-3.6.1.min.js"></script>
</head>
<body>
<button id="btn">按钮</button>
<script>
const btn = document.getElementById("btn");
alert($(btn));
alert($("#btn"));
</script>
</html>
④ 将html代码作为参数
会根据html
代码来创建元素(jQuery对象)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./js/jquery-3.6.1.min.js"></script>
</head>
<body>
<div></div>
<script>
var $h1 = $("<h1>我是一个h1标题</h1>");
$("div").append($h1);
</script>
</html>
5. jQuery对象
jQuery对象是jQuery中定义的对象,可以将其理解为是D0M对象的升级版,在jQuery对象中为我们提供了很多jQuery对象的方法来帮助我们简化DOM操作。
⑴ jQuery对象本质上是一个DOM对象的数组(类数组)可以通过索引获取jQuery对象中的DOM对象
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./js/jquery-3.6.1.min.js"></script>
</head>
<body>
<ul>
<li>唐僧</li>
<li>孙悟空</li>
<li>沙和尚</li>
</ul>
<script>
var $li = $("li");
console.log($li);
alert($li.length);
alert($li[0].textContent);
</script>
</html>
⑵ 当我们修改jQuery对象时,它会自动修改jQuery中的所有元素这一特点称为jQuery的隐式迭代
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./js/jquery-3.6.1.min.js"></script>
</head>
<body>
<button id="btn">按钮</button></button>
<ul>
<li id="ts">唐僧</li>
<li id="swk">孙悟空</li>
<li id="shs">沙和尚</li>
</ul>
<script>
const btn = document.getElementById("btn");
var $li = $("li");
btn.addEventListener("click",()=>{
var text = $li.text();//读取文本,返回所有标签中的文本
alert(text);
$li.text("啦啦啦");
var $id = $li.attr("id");//读取属性时,返回第一个标签的属性
alert($id);
});
</script>
</html>
⑶ 通常情况下,jQuery对象的方法的返回值依然是一个jQuery对象
通常情况下,jQuery对象的方法的返回值依然是一个jQuery对象,所以我们可以调用一个方法后继续调用其他的jQuery对象的方法。这一特性,称为jQuery对象的 链式调用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./js/jquery-3.6.1.min.js"></script>
</head>
<body>
<button id="btn">按钮</button></button>
<ul>
<li id="ts">唐僧</li>
<li id="swk">孙悟空</li>
<li id="shs">沙和尚</li>
</ul>
<script>
const btn = document.getElementById("btn");
var $li = $("li");
btn.addEventListener("click",()=>{
var result= $li.text("新文本内容");
result.css("color","red");
alert($li === result);
});
</script>
</html>
6. 常用方法
● addClass()
为jQuery对象添加一个或多个class
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./js/jquery-3.6.1.min.js"></script>
<style>
.d1{
width: 200px;
height: 200px;
background-color: gray
}
.d2{
background-color: yellow;
}
.d3{
border: 1px solid red;
}
.d4{
border-radius: 50px;
}
</style>
</head>
<body>
<button id="btn">按钮</button>
<div class="d1" id="d"></div>
<script>
//为按钮绑定响应函数
$("#btn").click(function(){
//为box1添加class,addClass()可以添加一个或多个class
$("#d").addClass(["d2","d3"]);
$("#d").addClass("d4");
});
</script>
</html>
● hasClass()
检查jQuery对象是否含有某个class
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./js/jquery-3.6.1.min.js"></script>
<style>
.d1{
width: 200px;
height: 200px;
background-color: gray
}
.d2{
background-color: yellow;
}
.d3{
border: 1px solid red;
}
.d4{
border-radius: 50px;
}
</style>
</head>
<body>
<button id="btn">按钮</button>
<div class="d1 d2 d3 d4" id="d"></div>
<script>
//为按钮绑定响应函数
$("#btn").click(function(){
//hasClass() 检查jQuery对象是否含有某个class
var flag = $("#d").hasClass("d1");
alert(flag);
});
</script>
</html>
● removeClass()
删除jQuery对象的指定class
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./js/jquery-3.6.1.min.js"></script>
<style>
.d1{
width: 200px;
height: 200px;
background-color: gray
}
.d2{
background-color: yellow;
}
.d3{
border: 1px solid red;
}
.d4{
border-radius: 50px;
}
</style>
</head>
<body>
<button id="btn">按钮</button>
<div class="d1 d2 d3 d4" id="d"></div>
<script>
//为按钮绑定响应函数
$("#btn").click(function(){
//removeClass()删除jQuery对象的指定class
var flag = $("#d").removeClass("d4");
});
</script>
</html>
● toggleClass()
切换jQuery对象的指定class
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./js/jquery-3.6.1.min.js"></script>
<style>
.d1{
width: 200px;
height: 200px;
background-color: gray
}
.d2{
background-color: yellow;
}
.d3{
background-color: rebeccapurple;
}
.d4{
border-radius: 50px;
}
</style>
</head>
<body>
<button id="btn">按钮</button>
<div class="d1 d2 d3 d4" id="d"></div>
<script>
//为按钮绑定响应函数
$("#btn").click(function(){
//toggleClass() 切换jQuery对象的指定class
var flag = $("#d").toggleClass(["d3","d4"]);
});
</script>
</html>
● clone()
复制jQuery元素,当参数为true,元素上的事件也会被复制
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./js/jquery-3.6.1.min.js"></script>
</head>
<body>
<button id="btn">添加</button>
<ul id="list1">
<li>猪八戒</li>
<li>沙和尚</li>
<li>唐僧</li>
</ul>
<ul id="list2">
<li>牛魔王</li>
<li id="l1">铁扇公主</li>
<li>红孩儿</li>
</ul>
<script>
//为按钮绑定响应函数
$("#btn").click(function(){
var $l1 = $("#l1").clone();
$("#list1").append($l1);
});
</script>
</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>
<script src="./js/jquery-3.6.1.min.js"></script>
</head>
<body>
<button id="btn">添加</button>
<ul id="list1">
<li>猪八戒</li>
<li>沙和尚</li>
<li>唐僧</li>
</ul>
<ul id="list2">
<li>牛魔王</li>
<li id="l1">铁扇公主</li>
<li>红孩儿</li>
</ul>
<script>
//为铁扇公主的li绑定点击事件
$("#l1").click(function(){
alert("我是铁扇公主~");
});
//为按钮绑定响应函数
$("#btn").click(function(){
//复制jQuery元素,当参数为true,元素上的事件也会被复制
var $l1 = $("#l1").clone(true);
$("#list1").append($l1);
});
</script>
</html>
● unwrap()
去除父元素
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./js/jquery-3.6.1.min.js"></script>
<style>
div{
width: 300px;
height: 300px;
background-color: greenyellow;
}
</style>
</head>
<body>
<button id="btn">去除</button>
<div>
<ul id="list">
<li>牛魔王</li>
<li id="l1">铁扇公主</li>
<li>红孩儿</li>
</ul>
</div>
<script>
//为按钮绑定响应函数
$("#btn").click(function(){
var $l1 = $("#list").unwrap("div");
});
</script>
</html>
● wrap()
添加父元素
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./js/jquery-3.6.1.min.js"></script>
<style>
#d1{
width: 300px;
height: 300px;
background-color: greenyellow;
}
#d2{
width: 300px;
height: 300px;
background-color: red;
}
</style>
</head>
<body>
<button id="btn">去除</button>
<button id="addbtn">添加</button>
<div id="d1">
<ul id="list">
<li>牛魔王</li>
<li id="l1">铁扇公主</li>
<li>红孩儿</li>
</ul>
</div>
<hr/>
<div id="d2"></div>
<script>
//为按钮绑定响应函数
$("#btn").click(function(){
var $l1 = $("#list").unwrap("#d1");
});
//为按钮绑定响应函数
$("#addbtn").click(function(){
var $l1 = $("#list").wrap("#d2");
});
</script>
</html>
● wrapAll()
添加父元素 (当前所有的元素看成一个整体添加元素)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./js/jquery-3.6.1.min.js"></script>
<style>
#d2{
width: 300px;
height: 300px;
background-color: red;
}
</style>
</head>
<body>
<button id="addbtn">添加</button>
<ul id="list">
<li>牛魔王</li>
<li>铁扇公主</li>
<li>红孩儿</li>
</ul>
<hr/>
<div id="d2"></div>
<script>
//为按钮绑定响应函数
$("#addbtn").click(function(){
var $l1 = $("#list li").wrapAll("#d2");
});
</script>
</html>
● wrapInner()
在元素内部增加一层
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./js/jquery-3.6.1.min.js"></script>
<style>
#d2{
width: 300px;
height: 300px;
background-color: red;
}
</style>
</head>
<body>
<button id="addbtn">添加</button>
<ul id="list">
<li id="d">牛魔王</li>
<li>铁扇公主</li>
<li>红孩儿</li>
</ul>
<hr/>
<div id="d2"></div>
<script>
//为按钮绑定响应函数
$("#addbtn").click(function(){
var $l1 = $("#list #d").wrapInner("#d2");
});
</script>
</html>
● append()
添加子元素
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./js/jquery-3.6.1.min.js"></script>
</head>
<body>
<button id="btn">添加</button>
<ul id="list1">
<li>猪八戒</li>
<li>沙和尚</li>
<li>唐僧</li>
</ul>
<ul id="list2">
<li>牛魔王</li>
<li id="l1">铁扇公主</li>
<li>红孩儿</li>
</ul>
<script>
//为铁扇公主的li绑定点击事件
$("#l1").click(function(){
alert("我是铁扇公主~");
});
//为按钮绑定响应函数
$("#btn").click(function(){
//复制jQuery元素,当参数为true,元素上的事件也会被复制
var $l1 = $("#l1").clone(true);
$("#list1").append($l1);
});
</script>
</html>
● appendTo()
添加到父元素
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./js/jquery-3.6.1.min.js"></script>
</head>
<body>
<button id="btn">添加</button>
<ul id="list1">
<li>猪八戒</li>
<li>沙和尚</li>
<li>唐僧</li>
</ul>
<ul id="list2">
<li>牛魔王</li>
<li id="l1">铁扇公主</li>
<li>红孩儿</li>
</ul>
<script>
//为铁扇公主的li绑定点击事件
$("#l1").click(function(){
alert("我是铁扇公主~");
});
//为按钮绑定响应函数
$("#btn").click(function(){
//复制jQuery元素,当参数为true,元素上的事件也会被复制
var $l1 = $("#l1").clone(true);
$l1.appendTo($("#list1"));
});
</script>
</html>
● prepend()
向前添加子元素
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./js/jquery-3.6.1.min.js"></script>
</head>
<body>
<button id="btn">添加</button>
<ul id="list1">
<li>猪八戒</li>
<li>沙和尚</li>
<li>唐僧</li>
</ul>
<ul id="list2">
<li>牛魔王</li>
<li id="l1">铁扇公主</li>
<li>红孩儿</li>
</ul>
<script>
//为铁扇公主的li绑定点击事件
$("#l1").click(function(){
alert("我是铁扇公主~");
});
//为按钮绑定响应函数
$("#btn").click(function(){
//复制jQuery元素,当参数为true,元素上的事件也会被复制
var $l1 = $("#l1").clone(true);
$("#list1").prepend($l1);
});
</script>
</html>
● prependTo()
添加到父元素前
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./js/jquery-3.6.1.min.js"></script>
</head>
<body>
<button id="btn">添加</button>
<ul id="list1">
<li>猪八戒</li>
<li>沙和尚</li>
<li>唐僧</li>
</ul>
<ul id="list2">
<li>牛魔王</li>
<li id="l1">铁扇公主</li>
<li>红孩儿</li>
</ul>
<script>
//为铁扇公主的li绑定点击事件
$("#l1").click(function(){
alert("我是铁扇公主~");
});
//为按钮绑定响应函数
$("#btn").click(function(){
//复制jQuery元素,当参数为true,元素上的事件也会被复制
var $l1 = $("#l1").clone(true);
$l1.prependTo($("#list1"));
});
</script>
</html>
● html()
读取或设置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>
<script src="./js/jquery-3.6.1.min.js"></script>
</head>
<body>
<button id="btn">添加</button>
<ul id="list1">
<li>猪八戒</li>
<li>沙和尚</li>
<li>唐僧</li>
</ul>
<ul id="list2">
<li>牛魔王</li>
<li id="l1">铁扇公主</li>
<li>红孩儿</li>
</ul>
<script>
//为铁扇公主的li绑定点击事件
$("#l1").click(function(){
alert("我是铁扇公主~");
});
//为按钮绑定响应函数
$("#btn").click(function(){
alert($("#list2").html());
});
</script>
</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>
<script src="./js/jquery-3.6.1.min.js"></script>
</head>
<body>
<button id="btn">添加</button>
<ul id="list1">
<li>猪八戒</li>
<li>沙和尚</li>
<li>唐僧</li>
</ul>
<ul id="list2">
<li>牛魔王</li>
<li id="l1">铁扇公主</li>
<li>红孩儿</li>
</ul>
<script>
//为铁扇公主的li绑定点击事件
$("#l1").click(function(){
alert("我是铁扇公主~");
});
//为按钮绑定响应函数
$("#btn").click(function(){
$("#list2").html("<li>蜘蛛精</li><li>玉兔精</li><li>大象精</li></li>");
});
</script>
</html>
● text()
读取或设置文本内容
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./js/jquery-3.6.1.min.js"></script>
</head>
<body>
<button id="btn">点我一下</button>
<ul id="list1">
<li>猪八戒</li>
<li>沙和尚</li>
<li>唐僧</li>
</ul>
<ul id="list2">
<li>牛魔王</li>
<li id="l1">铁扇公主</li>
<li>红孩儿</li>
</ul>
<script>
//为铁扇公主的li绑定点击事件
$("#l1").click(function(){
alert("我是铁扇公主~");
});
//为按钮绑定响应函数
$("#btn").click(function(){
alert($("#l1").text());
});
</script>
</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>
<script src="./js/jquery-3.6.1.min.js"></script>
</head>
<body>
<button id="btn">点我一下</button>
<ul id="list1">
<li>猪八戒</li>
<li>沙和尚</li>
<li>唐僧</li>
</ul>
<ul id="list2">
<li>牛魔王</li>
<li id="l1">铁扇公主</li>
<li>红孩儿</li>
</ul>
<script>
//为铁扇公主的li绑定点击事件
$("#l1").click(function(){
alert("我是铁扇公主~");
});
//为按钮绑定响应函数
$("#btn").click(function(){
$("#l1").text("玉面狐狸");
});
</script>
</html>
● after()
向后边添加元素(添加的师兄弟元素)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./js/jquery-3.6.1.min.js"></script>
</head>
<body>
<button id="btn">点我一下</button>
<ul id="list1">
<li>猪八戒</li>
<li>沙和尚</li>
<li>唐僧</li>
</ul>
<ul id="list2">
<li>牛魔王</li>
<li id="l1">铁扇公主</li>
<li>红孩儿</li>
</ul>
<script>
//为铁扇公主的li绑定点击事件
$("#l1").click(function(){
alert("我是铁扇公主~");
});
//为按钮绑定响应函数
$("#btn").click(function(){
//after() 向后边添加元素(添加的师兄弟元素)
$("#l1").after($("<li>张三</li>"));
});
</script>
</html>
● insertAfter()
将元素添加到某元素的后边(添加的师兄弟元素)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./js/jquery-3.6.1.min.js"></script>
</head>
<body>
<button id="btn">点我一下</button>
<ul id="list1">
<li>猪八戒</li>
<li>沙和尚</li>
<li>唐僧</li>
</ul>
<ul id="list2">
<li>牛魔王</li>
<li id="l1">铁扇公主</li>
<li>红孩儿</li>
</ul>
<script>
//为铁扇公主的li绑定点击事件
$("#l1").click(function(){
alert("我是铁扇公主~");
});
//为按钮绑定响应函数
$("#btn").click(function(){
//insertAfter() 将元素添加到某元素的后边(添加的师兄弟元素)
$("<li>张三</li>").insertAfter($("#l1"));
});
</script>
</html>
● before()
向前边添加元素(添加的师兄弟元素)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./js/jquery-3.6.1.min.js"></script>
</head>
<body>
<button id="btn">点我一下</button>
<ul id="list1">
<li>猪八戒</li>
<li>沙和尚</li>
<li>唐僧</li>
</ul>
<ul id="list2">
<li>牛魔王</li>
<li id="l1">铁扇公主</li>
<li>红孩儿</li>
</ul>
<script>
//为铁扇公主的li绑定点击事件
$("#l1").click(function(){
alert("我是铁扇公主~");
});
//为按钮绑定响应函数
$("#btn").click(function(){
//after() 向后边添加元素(添加的师兄弟元素)
$("#l1").before($("<li>张三</li>"));
});
</script>
</html>
●insertBefore()
将元素添加到某元素的前边(添加的师兄弟元素)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./js/jquery-3.6.1.min.js"></script>
</head>
<body>
<button id="btn">点我一下</button>
<ul id="list1">
<li>猪八戒</li>
<li>沙和尚</li>
<li>唐僧</li>
</ul>
<ul id="list2">
<li>牛魔王</li>
<li id="l1">铁扇公主</li>
<li>红孩儿</li>
</ul>
<script>
//为铁扇公主的li绑定点击事件
$("#l1").click(function(){
alert("我是铁扇公主~");
});
//为按钮绑定响应函数
$("#btn").click(function(){
//insertAfter() 将元素添加到某元素的后边(添加的师兄弟元素)
$("<li>张三</li>").insertBefore($("#l1"));
});
</script>
</html>
● detach()
删除元素(保留元素上的事件)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./js/jquery-3.6.1.min.js"></script>
</head>
<body>
<button id="btn">删除</button>
<button id="btn2">添加</button>
<ul id="list1">
<li>猪八戒</li>
<li>沙和尚</li>
<li>唐僧</li>
</ul>
<ul id="list2">
<li>牛魔王</li>
<li id="l1">铁扇公主</li>
<li>红孩儿</li>
</ul>
<script>
//为铁扇公主的li绑定点击事件
$("#l1").click(function(){
alert("我是铁扇公主~");
});
var $l1 = $("#l1");
//为按钮绑定响应函数
$("#btn").click(function(){
//删除铁扇公主
$l1.detach();
});
$("#btn2").click(function(){
//删除铁扇公主
$("#list2").append($l1);
});
</script>
</html>
● empty()
删除所有子元素
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./js/jquery-3.6.1.min.js"></script>
</head>
<body>
<button id="btn">删除</button>
<ul id="list1">
<li>猪八戒</li>
<li>沙和尚</li>
<li>唐僧</li>
</ul>
<ul id="list2">
<li>牛魔王</li>
<li id="l1">铁扇公主</li>
<li>红孩儿</li>
</ul>
<script>
//为铁扇公主的li绑定点击事件
$("#l1").click(function(){
alert("我是铁扇公主~");
});
var $list2 = $("#list2");
//为按钮绑定响应函数
$("#btn").click(function(){
//清空列表
$list2.empty();
});
</script>
</html>
●remove()
删除元素
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./js/jquery-3.6.1.min.js"></script>
</head>
<body>
<button id="btn">删除</button>
<button id="btn2">添加</button>
<ul id="list1">
<li>猪八戒</li>
<li>沙和尚</li>
<li>唐僧</li>
</ul>
<ul id="list2">
<li>牛魔王</li>
<li id="l1">铁扇公主</li>
<li>红孩儿</li>
</ul>
<script>
//为铁扇公主的li绑定点击事件
$("#l1").click(function(){
alert("我是铁扇公主~");
});
var $l1 = $("#l1");
//为按钮绑定响应函数
$("#btn").click(function(){
//删除铁扇公主
$l1.remove();
});
$("#btn2").click(function(){
//删除铁扇公主
$("#list2").append($l1);
});
</script>
</html>
● replaceAll()
替换某个元素
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./js/jquery-3.6.1.min.js"></script>
</head>
<body>
<button id="btn">替换</button>
<ul id="list1">
<li>猪八戒</li>
<li>沙和尚</li>
<li>唐僧</li>
</ul>
<ul id="list2">
<li>牛魔王</li>
<li id="l1">铁扇公主</li>
<li>红孩儿</li>
</ul>
<script>
//为铁扇公主的li绑定点击事件
$("#l1").click(function(){
alert("我是铁扇公主~");
});
//为按钮绑定响应函数
$("#btn").click(function(){
//替换铁扇公主
$("<li>玉面狐狸</li></li>").replaceAll($("#l1"));
});
</script>
</html>
● replaceWith()
被某个元素替换
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./js/jquery-3.6.1.min.js"></script>
</head>
<body>
<button id="btn">替换</button>
<ul id="list1">
<li>猪八戒</li>
<li>沙和尚</li>
<li>唐僧</li>
</ul>
<ul id="list2">
<li>牛魔王</li>
<li id="l1">铁扇公主</li>
<li>红孩儿</li>
</ul>
<script>
//为铁扇公主的li绑定点击事件
$("#l1").click(function(){
alert("我是铁扇公主~");
});
//为按钮绑定响应函数
$("#btn").click(function(){
//替换铁扇公主
$("#l1").replaceWith($("<li>玉面狐狸</li></li>"));
});
</script>
</html>
● attr()
设置/获取元素的指定属性,布尔值属性会返回实际值
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./js/jquery-3.6.1.min.js"></script>
</head>
<body>
<button id="btn">获取属性值</button>
<hr/>
<input type="text" readonly></input>
<script>
//为按钮绑定响应函数
$("#btn").click(function(){
alert($("input").attr("type"));
alert($("input").attr("readonly"));
$("input").attr("value","姓名")
});
</script>
</html>
v ● prop()
设置/获取元素的指定属性,布尔值属性会返回布尔值
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./js/jquery-3.6.1.min.js"></script>
</head>
<body>
<button id="btn">获取属性值</button>
<hr/>
<input type="text" readonly></input>
<script>
//为按钮绑定响应函数
$("#btn").click(function(){
alert($("input").prop("type"));
alert($("input").prop("readonly"));
$("input").prop("value","姓名")
});
</script>
</html>
● removeAttr()
移除属性
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./js/jquery-3.6.1.min.js"></script>
</head>
<body>
<button id="btn">获取属性值</button>
<hr/>
<input type="text" readonly value="请填入姓名"></input>
<script>
//为按钮绑定响应函数
$("#btn").click(function(){
$("input").removeAttr("readonly");
$("input").removeAttr("value");
});
</script>
</html>
● val()
设置/获取元素的value属性
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./js/jquery-3.6.1.min.js"></script>
</head>
<body>
<button id="btn">设置value</button>
<button id="btn2">获取value</button>
<hr/>
<input type="text" readonly></input>
<script>
//为按钮绑定响应函数
$("#btn").click(function(){
$("input").val("姓名")
});
$("#btn2").click(function(){
alert($("input").val());
});
</script>
</html>
● css()
读取/设置元素的css样式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./js/jquery-3.6.1.min.js"></script>
</head>
<body>
<button id="btn">设置css</button>
<button id="btn2">获取css</button>
<hr/>
<div></div>
<script>
//为按钮绑定响应函数
$("#btn").click(function(){
$("div").css("background-color","yellow")
$("div").css("width","200px")
$("div").css("height","200px")
});
$("#btn2").click(function(){
alert($("div").css("background-color"));
alert($("div").css("width"));
alert($("div").css("height"));
});
</script>
</html>
● height()
读取/设置元素的高度
● width()
读取/设置元素的宽度
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./js/jquery-3.6.1.min.js"></script>
</head>
<body>
<button id="btn">设置css</button>
<button id="btn2">获取css</button>
<hr/>
<div></div>
<script>
//为按钮绑定响应函数
$("#btn").click(function(){
$("div").css("background-color","yellow")
$("div").height("200px")
$("div").width("200px")
});
$("#btn2").click(function(){
alert($("div").css("background-color"));
alert($("div").css("width"));
alert($("div").css("height"));
});
</script>
</html>
● innerHeight()
读取/设置元素的内部高度
● innerWidth()
读取/设置元素的内部宽度
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./js/jquery-3.6.1.min.js"></script>
</head>
<body>
<button id="btn">设置css</button>
<button id="btn2">获取css</button>
<hr/>
<div></div>
<script>
//为按钮绑定响应函数
$("#btn").click(function(){
$("div").css("background-color","yellow");
$("div").css("padding","10px");
$("div").height("200px")
$("div").width("200px")
});
$("#btn2").click(function(){
alert($("div").css("background-color"));
alert($("div").css("width"));
alert($("div").css("height"));
alert($("div").innerHeight());
$("div").innerWidth("100px");
alert($("div").innerWidth());
});
</script>
</html>
● outerHeight()
读取/设置元素可见框的高度
● outerWidth()
读取/设置元素可见框的宽度
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./js/jquery-3.6.1.min.js"></script>
</head>
<body>
<button id="btn">设置css</button>
<button id="btn2">获取css</button>
<hr/>
<div></div>
<script>
//为按钮绑定响应函数
$("#btn").click(function(){
$("div").css("background-color","yellow");
$("div").outerHeight("100px");
$("div").outerWidth("100px");
});
$("#btn2").click(function(){
alert($("div").css("background-color"));
alert($("div").outerHeight());
alert($("div").outerWidth());
});
</script>
</html>
● offset()
读取/设置元素的偏移量
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./js/jquery-3.6.1.min.js"></script>
<style>
div{
height: 300px;
width: 300px;
background-color: yellow;
}
</style>
</head>
<body>
<button id="btn">设置坐标</button></button>
<button id="btn2">获取坐标</button>
<hr/>
<div></div>
<script>
//为按钮绑定响应函数
$("#btn").click(function(){
$("div").offset({top:"200",left:"300"});
});
$("#btn2").click(function(){
alert($("div").offset().top);
alert($("div").offset().left);
});
</script>
</html>
● position()
读取元素相当于包含块的偏移量
● scrollLeft()
读取/设置元素水平滚动条的位置
● scrollTop()
读取/设置元素垂直滚动条的位置
● eq()
获取指定索引的元素
● even()
获取索引为偶数的元素
● odd()
获取索引为奇数的元素
● filter()
筛选元素
● first()
获取第一个元素
● last()
获取最后一个元素
● has()
获取含有指定后代的元素
● is()
检查是否含有某元素
● map()
获取对象中的指定数据
● slice()
截取元素(切片)
● add()
创建包含当前元素的新的jQuery对象
● addBack()
将之前操作的集合中的元素添加到当前集合中
● contents()
获取当前jQuery对象的所有子节点(包括文本节点)
● end()
将筛选过的列表恢复到之前的状态
● not()
从列表中去除符合条件的元素
● children()
获取子元素
● closest()
获取离当前元素最近的指定元素
● find()
查询指定的后代元素
● next()
获取后一个兄弟元素
● nextAll()
获取后边所有的兄弟元素
● nextUntil()
获取后边指定位置的兄弟元素
● offsetParent()
获取定位父元素
● parent()
获取父元素
● parents()
获取所有的祖先元素
● parensUntil()
获取指定的祖先元素
● prev()
获取前边的兄弟元素
● prevAll()
获取前边所有的兄弟元素
● prevUntil()
获取指定的兄弟元素
● siblings()
获取所有的兄弟元素