javascrit前端

一.简介

1.javascript是什么

  • javascript是一中远行在客户端(浏览器)的编程语言,实现人机交互效果
  • javaScript是一门跨平台、面向对象的脚本语言(不需要编译,直接解释运行即可),来控制网页的行为,它能使网页可交互
  • javascrit由ECMAScript(基础语法),web APis (DOM,BOM)

2.javascrit书写位置

​ 内部,外部,行内

内部

  • 在HTML中,JavaScript代码必须位于sctipt与/sctipt标签之间
  • 内部书写javascrit:将JS代码定义在HTML页面中
1
2
3
4
<script>
//页面弹出警告
alert("hello,javascrit!!!")
</script>

外部

  • 外部书写javascrit:将JS代码定义在外部JS文件中,然后引入HTML页面中
1
<script src="./文件地址"></script>

注意

  • 外部文件不能包含script标签

  • script标签不能自闭合,必须写成script /script

  • 在HTML文档中可以在任意地方,放置任意数量的 script

  • 一般把脚本置于 body 元素的底部,可改善显示速度,因为脚本执行会拖慢显示

3.javascript写注释方式

(1).单行注释

  1. ​ 符号://
    . 快捷键:ctrl+/
1
2
3
<script>
//单行注释
</script>

(2).块注释

​ 符号:/* */

​ 快捷键:shift+alt+a

1
2
3
4
5
<script>
/* 块注释
块注释
块注释 */
</script>

4.javascript结束符

  • 结束符:;
  • 结束符可写可不写

二.基础语法

1.输入输出语法

(1)输出语法:

​ <1>

1
2
3
4
<script>
document.write("<h1>我是h1标签</h1>")
document.write("我是h1标签")
</script>

作用

  • 向body内输入内容
  • 如果输出内容写的是标签,则会被解析为网页元素
1
2
3
<script>
alert("页面弹出警示对话框")
</script>

作用

  • 页面弹出警示对话框
1
2
3
<script>
console.log("控制台打印输出")
</script>

作用

  • 控制台输出语法,程序员调试使用

(2).输入语法:

1
2
3
<script>
prompt("请输入你要输入的内容")
</script>

2.变量

  • 变量用let来声明
1
2
3
4
5
6
7
8
9
10
11
<script>//变量用let来声明
//声明一个name变量
let name
//将name赋值为20
name=20
//打印变量
document.write(name)
//变量的初始化
let date=2024
document.write(date)
</script>
1
2
3
4
<script>
let name='爱丽丝' ,sume=20
document.write(name,sume)
</script>
  • 更新变量:直接将变量赋值就OK了(与C++一样)

  • 也可以声明多个变量,输出多个变量(与C++差不多)

  • 变量命名的规则:

    不能用关键字

    只能使用下划线,字母,数字,字符$组成,而且数字不能开头

    字母要严格区分大小写

let和var的区别

在较旧的javascript中,使用关键字var来声明变量,而不是let

现在的开发中一般不是用var,只是我们可以在更老的程序中看到它

let是为了解决var的一些问题

var声明:

  1. 可以先使用,再声明(不合理)
  2. var声明过的变量可以重复声明
  3. 比如变量提升,全局变量,没有块级作用域等等

3.数组

(1).数组的声明

let 数组名字=[数据1,数据2……,数据n]

(2).数组的使用

数组名字[数组下标索引]

(3).数组的长度

数组名字.length

1
2
3
4
5
6
7
8
<script>
//声明数组
let arr=[12,23,34,45,56]
//打印数组
document.write(arr[2])
//打印数组长度
document.write(arr.length)
</script>

(4).数组的操作

1.数组添加新的数据:
  • 数组名.push(新增加的内容)

    将一个或者多个元素添加到数组的末尾,并返回该数组的新长度

  • 数组名.unshift(新增的内容)

    将一个或者多个元素添加到数组的开头,并返回该数组的新长度

2.数组删除旧有的数据:
  • 数组名.pop()

    从数组中删除最后一个元素,并返回该元素的值

  • 数组名.shift()

    删除数组中第一个元素

  • 数组名.splice(操作的下标,删除的个数)

    数组名.splice(起始位置,删除的个数)

    如果删除的个数不写的话,默认从指定位置删除到最后

3.数组名.sort()
1
2
3
4
5
6
7
<script>
let arr=[]
//升序
arr.sort(function(a,b){return a-b})
//降序
arr.sort(function(a,b){return b-a})
</script>
4.join()

该方法以指定参数作为分割符,将所有数组连接为一个字符串返回

如果没有参数,默认以逗号分割

如果数组成员是undefined或者null或者空位,那么会被转化为空字符串

数组的join配合字符串的split可以实现数组与字符串之间的转换

1
2
3
4
5
6
7
8
9
10
<script>
let app=[12,23,34,45,6,7,3,42,34,24,3,5,354]
document.write(app.join())
document.write(app.join(""))
document.write(app.join("|"))

let spp=["hello","world"]
let dpp=spp.join("")
document.write(dpp.split(""))
</script>
5.concat()

用于多个数组的合并,将新数组的成员添加到原数组的后面,然后返回一个新数组,原数组不变

除了数组作为参数,concat()也接受其他类型的值作为参数,添加到目标数组的尾部

1
2
3
4
5
6
<script>
let app=[12,23,3,4,4322,3]
let spp=[12,23,24,423,24,2,32,3]
document.write(app.concat(spp))
document.write(app.concat(111111111111,2,3,2,32,4,123,12,523,42,14,123))
</script>
6.reversr()

该方法用于颠倒数组元素,返回改变后的数组,但是该方法会改变原数组

1
2
3
4
5
6
7
8
9
10
11
<script>
let app=[12,23,3,4,4322,3]
console.log(app)
app.reverse()
console.log(app)
//同时也可以·用来翻转字符串,先将字符串转化为数组,再利用数组的翻转,然后再利用join重新转化为字符串
let spp="我不再孤单"
let dpp=spp.split("")
dpp.reverse()
console.log(dpp.join(""))
</script>
7.indexOf()

该方法放回给定元素在数组中第一次出现的位置,返回元素下标,如果没有则返回-1

还可以有第二个参数,表示开始查找的位置

1
2
3
4
5
6
7
8
<script>
let app=[12,23,34,4,523,42,5,2]
document.write(app.indexOf(2))
document.write(app.indexOf(22222))
//不存在则返回-1
document.write(app.indexOf(4,5))
//从小标为5的开始往后面开始寻早该数组中是否有4
</script>

(5).数组定义

数组内可以添加任意类型的数据,数组里包括数组称为二维数组

(6).可以利用for … in 遍历数组(增强for、循环)

1
2
3
4
5
6
7
<script>
let app=[12,23,34,45,6,7,3,42,34,24,3,5,354]
for(let s1 in app)
{
document.write(s1)
}
</script>

(7).数组静态方法Array.isArray()

tepdof不能判断一个数据到底是不是数据这个数据类型

这时就可以利用这个方法来判断是不是是数组

利用Array.isArray()可以判断

如果返回的false,则不是数组,如果返回的是true,那么就是数组

1
2
3
4
<script>
let app=[12,23,34,45,6,7,3,42,34,24,3,5,354]
document.write(Array.isArray(app))
</script>

(!!!).补充的知识点

1.数组中的map的用法:

72304290994

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
let arr=['红色','白色','绿色','蓝色','粉红色']
let srr= arr.map(function(app,key)//app代表的是值,key代表的是数组的下标
{
return app+'I do not know!!!'
}
)
console.log(srr);
</script>
</body>
</html>
2.数组中join方法得用法:

72304378489

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
let arr=['红色','白色','绿色','蓝色','粉红色']
console.log(arr.join())//当小括号为空的时候,则用逗号分割开
console.log(arr.join(''))//当小括号中为空字符的时候,则元素之间没有分隔符
console.log(arr.join('|||'))//字符之间以|||分割
</script>
</body>
</html>

72310026297

3.遍历数组的方法forEach

语法与map的相类似

72350979876

但是这个方法他不会返回一个数组

72351004799

1
2
3
4
5
6
7
<script>
let arr=['blue','red','gree']
arr.forEach(function(a,b){//这个其中的a是必须要写的,其中的b可以不用写,这个方法主要是遍历数组
console.log(a);
console.log(b);//这个方法没有return这个写法
})//这个方法适合用来遍历数组对象
</script>
4.筛选数组方法

72351482370

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<script>
let arr=[12,23,2,13,1243,12,423,3,1241,2]
//filter的用法
let arr1=arr.filter(function(app,index){
// console.log(app);
// console.log(index);
return app>=9//有返回的值,最后返回的是一个数组
})
console.log(arr1);

//除此之外,还有更简单的方法来写
let arr2=arr.filter(item=>item>=30)
console.log(arr2);
</script>

4.字符串

(1).转义

在字符串中,字符串中不可以双引号中包括双引号的形式,或者单引号包括单引号的形式

如果需要以上的操作,可以使用反斜杠的形式来表示,类似以C++的形式

1
2
3
4
5
6
7
8
9
<script>
let stl="string字符串"
let stl1="string字符串,其中'string'用单引号"
let stl2='string字符串,其中"string"用双引号'
// let stl2="string字符串,其中"string"用双引号"
//错误,因为双引号中不能用双引号,正确的·写法为:
let stl3="string字符串,其中\"string\"用了转义的双引号"
//还有一个单引号,在这里就不再写出来了,自行脑补
</script>

(2).字符串的长度

字符串的名字.length

1
2
3
4
<script>
let stl="string字符串"
document.write(stl.length)
</script>

(3).charAt()

返回指定位置的字符,参数时数字,位置是从0开始的

当为负数的时候或者超出字符串的长度的时候,返回的是空字符串

basic
1
2
3
4
5
6
7
8
<script>
let stl="string字符串"
document.write(stl.charAt(2))
document.write(stl.charAt(stl.length-1))
document.write(stl.charAt(-3))
document.write(stl.charAt(stl.length+5))
//当为负数的时候或者超出字符串的长度的时候,返回的是空字符串
</script>

(4).concat()

合并两或者多个字符串,成为一个新的字符串,同时不改变原来的字符串

可以使用加号来连接字符串

concat()和加号还是有区别的:

concat()不关是2什么的数据类型直接相拼接;但是加号如果遇到了数字类型的话,会先进行运算,遇到字符串的时候再变成字符串相连接

1
2
3
4
5
6
7
8
9
<script>
let str1="helllo"
let str2="world"
let str3="!"
document.write(str1.concat(str2))
document.write(str1.concat(str2,str3))
let app=str1.concat(str2,str3)
document.write(app)
</script>

(5)..substring()

字符串名字.subtring(起始的位置的数字,结束时的位置的数字下标)

其中不包括·结束位置的那个字符

如果直邮一个数字,那么表示的是从这个数字下标的字符一直到结束的字符为止

如果结束位置的下标数字小于起始位置下标数字,那么两个数字将调换

如果一个数字是负数,那么这个数字将转换为0

1
2
3
4
5
6
7
<script>
let app="这是一个字符串string"
document.write(app.substring(3,app.length))
document.write(app.substring(4))
document.write(app.substring(-4,6))
document.write(app.substring(6,2))
</script>

(6).substr()

substr方法从原字符串取出子字符串并返回,不改变原字符串,跟上面的substring方法的相同

不同之处就在于第一个参数代表的是起始位置,第二个参数代表的是·字=子字符串的长度

如果只有一个数字,那么表示的是从起始位置一直到结束的子字符串

如果第一个参数是负数,那么代表的是倒着计算字符的位置

入过第二个残数是负数,那么第二个参数会自动转化为0,最后返回一个空字符串

(7).indexof()

参数是字符或者字符串,表示的是寻找在这个字符串中有没有相对应的字符或者字符串

返回的是对应字符的下标数字,如果是字符串,那么返回的是对应字符串的第一个字符所对应的下标数字

也可以有第二个参数,第二个参数为数字,表示的是从这个字符串的第几个字符下标数字开始寻找

如果寻找不到这个字符或者字符串的话那么就会返回-1

1
2
3
4
5
6
<script>
let app="这是一个字符串string"
console.log(app.indexOf(String))
console.log(app.indexOf(s))
console.log(app.indexOf(s,3))
</script>

(8).trim()

能够去掉字符串两端的空格

不能去掉中间的空格

不仅能去掉空格,还能去掉制表符,换行符,回车符

trimStart()可以去掉字符串头部的空格

trimEnd()可以去掉尾部的空格

1
2
3
4
5
<script>
let app=" 这是一个有空格的字符串 "
document.write(app.trim())
document.write(app.trimEnd())
</script>

(9).split()

按照一定规定分割字符串,返回一个由分割出来的子字符串组成的数组

如果分割规定为空字符,那么返回数组的成员是原字符的每一个字符

如果没有参数,那么返回的唯一成员就是原字符串

还可以有第二个参数,限定返回数组的最大成员数

1
2
3
4
5
6
<script>
let app="it|bai|zhan"
console.log(app.split("|"))
console.log(app.split(""))
//返回的是一个数组
</script>

5.常量

const 名字=数据

1
2
3
4
<script>
const app=19
document.write(app)
</script>
  • 使用const声明的变量称为常量
  • 使用const来声明,而不是let

注意:

  1. 常量不可以重新赋值,声明的时候必须初始化
  2. 不需要重新赋值的数据可以使用const来命名

6.数据类型

javascript是弱数据类型语言

数据类型:

  1. 基本数据类型
  2. 引用数据类型

(1).基本数据类型

  1. number数字型

  2. string字符串型

    1.通过单引号(‘’),双引号(“”)或者反引号(`)包裹的数据都叫字符串

    ​ 单引号与双引号在本质上没有任何的区别

    • 无论是单引号还是双引号必须成对出现
    • 单引号和双引号可以相互嵌套,但是不可以自己嵌套自己(外双内单,或者外单内双)
    • 非必要的时候可以使用转义符\,输出单引号或者双引号

    2.字符串拼接:+运算符可以实现字符串的拼接

    3.字符串模板:

    语法:``(反引号)

    内容拼接时,用${变量名字}

  3. boolean布尔型

    ​ 有两个数据值true和false

  4. undefined未定义型

    ​ 没有赋值的变量,就是未定义数据类型

  5. null空类型

    ​ 一个值:null

    ​ 空类型


    typeof运算符可以检测数据的类型

    ​ 有两种写法:

    ​ 1.作为运算符:typeof 变量名字

    ​ 2.函数形式:typeof(变量名字)

    有括号和没有括号是一样的

(2).引用数据类型

  • object对象

(3)算术运算符

+ - * / %

(4).NaN

  • NaN代表一个计算错误,它是一个不正确或者未定义的数字操作所得的结果
  • NaN是粘性的,任何对NaN的操作都会返回NaN
1
2
3
4
5
<script>
document.write("字符型数据"-19)//输出NaN
document.write(NaN+19)//输出NaN
document.write(NaN==NaN)//输出false
</script>

7.数据类型转换

使用表单,prompt()获取过来的数据默认是字符串类型的,因此不能直接进行加法运算

(1).隐式转换

  1. +号两边只要有一个是字符串,都会把另一个转换为字符串
  2. 除了+号以外的算术运算符,比如-*/等都会把数据转换为数字类型

+号作为正号解析可以转换为数字型

任何数据和字符串相加结果都是字符串

(2)显式转换

1.Number(数据)

​ 转成数字类型

​ 如果字符串内容里有非数字,转换失败结果为NaN(Not a Number)即不是一个数字

​ NaN也是Number类型的数据,代表非数字

2.parseInt(数据)

​ 只保留整数

3、parseFloat(数据)

​ 可以保留小数

8.运算符

(1).赋值运算符

=

(2).一元运算符

自增:++

作用:让变量的值加1

前置自增:变量++(先用再加)

后置自增:++变量(先加再用)

自减:–

作用:让变量的值减1

前置自减:变量–(先用再减)

后置自减:–变量(先减再用)

(3).比较运算符

1.有大于,小于,大于等于,小于等于等等(这里不再写,与C++一样的语法)

=单等是赋值

==是判断(左右两边值是否相等)

===是全等(左右两边是否类型和值都相等)

!==(左右两边是否不全等)

  • 比较结果为boolean类型,即只会得到true或false

2.字符串比较,是比较对应的ASCLL码

从左到右依次比较

如果第一位一样再比较第二位,依次类推

  • NaN不等于任何值,包括它本身(只要涉及到NaN,都是false)
  • 尽量不要比较小数,因为小数有精度问题

(4).逻辑运算符

与C++一样

&&与

||或

!非

(5).运算符优先级

  1. 小括号 ()
  2. 一元运算符 ++ – !
  3. 算术运算符 先*/%后+-
  4. 关系运算符 > >= < <=
  5. 相等运算符 == != === !==
  6. 逻辑运算符 先&&后||
  7. 赋值运算符 =
  8. 逗号运算符 ,

(6).展开运算符

72343205178

72343248850

1
2
3
4
5
6
7
8
9
10
11
<script>
let arr1=[12,23,34,23,121,33]
console.log(...arr1);//展开运算符
//展开运算符的运用:1.求一个数组的最大值
let app=[12,23,24231,4,2]
console.log(Math.max(...app));
// 2.合并数组
let arr2=[12,23,34,45,5,66,7]
let arr=[...arr1,...arr2]
console.log(arr);//合并了arr1和arr2两个数组
</script>

9.语句

(1).分支语句

1.if语句

使用方式:单分支,双分支,多分支

单分支使用语法:

1
2
3
4
5
6
7
<script>
let app=19
if(app>10/* 条件 */)
{
document.write(app)//满足条件要执行的代码
}
</script>
  • 除了’ ‘ ,所有的字符串都为真
  • 除了0,所有数字都为真

双分支使用语法:

1
2
3
4
5
6
7
8
9
10
<script>
if(条件)
{
满足条件要执行的代码
}
else
{
不满足条件要执行的代码
}
</script>

多分支使用语法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<script>
if(条件1)
{
满足条件要执行的代码
}
else if(条件2)
{
满足条件要执行的代码
}
//......
else if(条件n)
{
满足条件要执行的代码
}
else
{
不满足所有条件要执行的代码
}
</script>

2.三元运算符

1
2
3
<script>
条件?代码1:代码2//三元运算符
</script>

3.switch语句

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<script>
switch(数据)
{
case 数据值1:代码1
break;
case 数据值2:代码1
break;
case 数据值3:代码1
break;
case 数据值4:代码1
break;
default:代码1
break;
}
</script>

switch具有穿透性,切记要加break

(2).循环语句

1.while循环

1
2
3
4
5
6
<script>
whlile(循环条件)
{
代码块
}
</script>
  • break:退出循环;
  • continue:结束本次循环,继续下次循环;

2.for循环

1
2
3
4
5
6
<script>
for(变量起始值;终止条件;变量变换量)
{
代码块
}
</script>
  • for循环和while循环的区别:
  • 当明确了循环的次数时使用for循环;当不明确循环的次数时使用while循环

10.函数

(1).函数的定义

1
2
3
4
function 函数名()
{
函数体
}

function 函数名(形参1,形参2,……,形参n)

(2).函数的命名规范

can 判断是否可以执行某个动作

has 判断是否含有某个值

is 判断是否为某个值

get 获取某个值

set 设置某个值

load 加载某些数据

(3).函数的调用

函数名()

函数提升:函数可以先用,在后面再定义

(4).函数放回值

用return来返回值

return后面的代码不会被执行,会立即结束当前函数

(5).函数细节

两个相同的函数,后面的会覆盖前面的函数

在javascript中,实参的个数和形参的个数可以不一致

  • 如果形参过多,会自动填上undefind
  • 如果实参过多,多余的实参会被忽略

函数一遇到return就不往下执行了,函数的结束用return

break与return的区别:

return结束的是函数,break结束的是循环或者switch

用数组可以实现返回多个值

(6).作用域

1.全局作用域

  • 全局有效
  • 作用于所用代码执行的环境(整个script标签内部)或者一个独立的js文件

2.局部作用域

  • 局部有效
  • 作用于函数内的代码环境

如果函数内部,变量没有声明,直接赋值,也当全局变量看

(7).匿名函数

  • 没有名字的函数,无法直接使用

匿名函数使用方法:

1.函数表达式:

将匿名函数赋值给一个变量,并且通过变量名称进行调用,称为函数表达式

1
2
3
4
5
6
7
8
<script>
let app=function()//函数表达式
{
函数体
}
app()//调用
//其中匿名函数的形参和实参使用和具名函数的一样
</script>

函数表达式和具名函数的不同之处:

  1. 具名函数的调用可以写到任何位置
  2. 函数表达式,必须先声明函数表达式,后调用

2.立即执行函数:

第一种写法:

1
2
3
4
5
<script>
(function(){/*代码体*/})();
//列如:
(function(x,y){console.log(x+y)})(1,8);
</script>

第二钟写法:

1
2
3
4
5
6
<script>
//语法
(function(){代码块}());
//列如:
(function(x,y,c){document.write(x+y+c)}(3,7,9));
</script>
  • 立即执行函数的作用:防止变量污染
  • 多个立即执行函数之间必须要用分号隔开

11.逻辑中断

(1).逻辑运算符中的短路

短路:只存在于&&和||中,当满足一定条件会让右边代码不执行

  1. &&:左边为false就短路
  2. ||:左边为ture就短路

原因:通过左边就能得到式子的结果,没有必要判断右边

1
2
3
4
 <script>
document.write(11&&22)//两个都为真,这时返回最后一个真值
document.write(22||11)//输出第一个真值
</script>

(2).转换为Boolean型

1.显示转换:Boolean(内容)

  • ‘’,0,undefined,null,false,NaN转换为布尔值后都是false,其余则为true

2.隐式转换:

  • 1.有字符串的加法””+1,结果是”1”
  • 2.减法-(像大多数数学运算一样)只能用于数字,他会使空字符串””转换为0
  • 3.null经过数字转换之后会变成0
  • 4.undefined经过数字转换之后会变成NaN

12.对象

对象是一种数据类型

(1).对象定义

let 对象名={ }

let 对象名=new Object( )

对象是由属性和方法组成

1.属性:信息或特征(名词)。

数据描述性的信息称为属性

属性都是成对出现的,包括属性名和值,他们之间用英文:分隔

多个属性之间使用英文,分隔

属性就是依附在对象上的变量(外面是变量,对象内是属性)

属性名可以使用””或’’,一般情况下省略,除非名称遇到特殊符号如空格,中横线等

2.方法:功能叫行为(动词)。

数据行为性的信息称为方法

方法是由方法名和函数两部分构成,他们之间使用:分隔

多个属性之间使用英文,分隔

方法是依附在对象中的函数

方法名可以使用””或’’,一般情况下省略,除非名称遇到特殊符号如空格,中横线等

(2).对象使用(属性)

1.查询对象

使用.获得对象中属性对应的值

语法:对象.属性

​ 或者

语法:对象名[‘属性’]

2.修改属性

语法:对象名.属性=新的值

3.增加属性

语法:对象名.新的属性= 新的值

4.删除属性

delate 对象名.属性

(3).对象使用(方法)

方法名:function(){代码块}

  • 方法中也可以添加形参和实参
  • 函数用的是匿名函数

调用:对象.方法名()

1
2
3
4
5
6
7
8
9
10
11
12
13
<script>
let app=
{
name:'daun',
age:19,
sex:'nan',
spp:function()
{
document.write('菜就多练,人生就两字,高墙')
}
}
app.spp()
</script>

(4).遍历对象

1
2
3
4
5
6
7
8
9
10
11
12
13
<script>
let app=
{
name:'春茂',
age:'19',
sex:'男'
}
for(let kkk in app)
{
document.write(kkk)//打印属性名
document.write(app[kkk])//打印属性值
}
</script>

类似于增强for循环的效果

1
2
3
4
5
6
let arr=['小学','初中','高中','大学']
for(let k in arr)
{
document.write(k)//数组的下标 索引号 但是都是字符串'0','1','2','3'
document.write(arr[k])//arr[k]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
let app=
{
name:'春茂',
age:'19',
sex:'男'
}
for(let kkk in app)
{
document.write(kkk)//得到的是属性名 'name','age','sex'
// document.write(app.name)
// document,write(app.kkk)相当于是document.write(app.'name')
document.write(app[kkk])//相当于document.write(app['name'])
}

还有数组对象:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<script>
let student=
[
{name:'春茂',age:'19',sex:'男'},
{name:'小红',age:'13',sex:'女'},
{name:'大名',age:'14',sex:'男'},
{name:'茂名',age:'16',sex:'男'}
]
for(let i=0;i<student.length;i++)
{
document.write(student[i].name)
document.write(student[i].age)
document.write(student[i].sex)
}
</script>

(5).内置对象

1.math对象

内置对象——Math

random:生成0-1之间的随机数(小数,包括0,不包括1)

ceil:向上取整

floor:向下取整

max:找最大数

min:找最小数

pow:幂运算

abs:绝对值

等等

生成0-10之间的随机数:

1
Math.floor(Math.random()*(10+1))

生成N到M之间的一个随机数:

1
Math.floor(Math.random()*(M-N+1))+N

可以将其封装为一个函数,方便得到随机数

2.date对象

date对象是javascript的原生时间库,以1970年1月1日00:00:00为时间的零点,可以表示的时间范围是前后的各一亿天(单位为毫秒)

date.now()

该方法返回的是当前时间距离时间零点的毫秒数

1
2
3
4
 <script>
Date.now()
document.write(Date.now())
</script>

时间戳

时间戳是指从北京时间1970年1月1日08:00:00到现在的总秒数

实例方法get类

  1. getTime():返回实例距离1970年1月1日00:00:00的毫秒数
  2. getDate():返回实例对象对应每个月的几号(从1开始)
  3. getDay():返回星期几,星期日为0,星期一为1,以此类推
  4. getYear():返回距离1900的年数
  5. getFullYear():返回四位的年份
  6. getMonth():返回月份 (0表示1月,11表示12月)
  7. getHours():返回小时(0-23)
  8. getMilliseconds():返回毫秒 (0-999)
  9. getMinutes():返回分钟(0-59)
  10. getSeconds():返回秒 (0-59)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<script>
Date.now()
document.write(Date.now())//1721488271120
console.log(new Date(1721488271120))//这个时间是固定不变的时间
console.log(Date(1721488271120))//返回的是当时的时间,会变化
console.log(new Date(1721488271120).getDate());
console.log(new Date(1721488271120).getDay());//返回星期几
console.log(new Date(1721488271120).getMonth());
//................
//做一个还有几天就可以过年的倒计时
let today=new Date()
let tomar=new Date(today.getFullYear(),11,31,23,59,59,999)
let s1=24*60*60*1000
let yes=(-today.getTime()+tomar.getTime())/s1
console.log(yes);
</script>

13.基本数据类型和引用数据类型

(1).基本数据类型

简单类型又叫做基本数据类型或者值类型

  • 在存储变量中存储的是值本身,因此叫做值类型
  • string,number,boolean,undefined,null

(2).引用数据类型

复杂类型又叫引用类型

  • 在存储变量时存储的仅仅是地址(引用),因此叫做引用数据类型
  • 通过new关键字创建的对象(系统对象,自定义对象),如Object,Array,Date等

(3).堆栈

  • 栈:由操作系统自动分配释放存放函数的参数值,局部变量的值等。其操作方式类似于数据结构里的栈;简单数据类型存放到栈里面
  • 堆:存储复杂类型(对象),一般由程序员分配释放,若程序员不释放,由垃圾回收机回收;引用数据类型存放到堆里面

三.Web APIS

1.变量声明

  • const声明的值不能改,而且const声明变量的时候需要里面进行初始化
  • 但是对于引用数据类型,const生命的变量,里面存的不是值,是地址

2.作用和分类

作用:使用js去操作html和浏览器

分类:DOM(文档对象模型),BOM(浏览器对象模型)

3.DOM

定义:用来呈现以及与任意HTML或XML文档交互的API

作用:开发网页内容特效和实现用户交互

(1).DOM树

将HTML文档以树状结构直观的表现出来,称之为文档树或DOM树

描述网页内容关系的名词

作用:文档树直观的体现了标签与标签之间的关系

节点的类型有七种
Document:整个文档树的顶层节点
DocumentType: doctype标签
Element:网页的各种HTML标签
Attribute:网页元素的属性(比如class=”right”)Text:标签之间或标签包含的文本
Comment:注释
DocumentFragment:文档的片段

(2).DOM对象

1.浏览器根据html标签生成的js对象

  • 所用的标签属性都可以在这个对象上面找到
  • 修改这个对象的属性会自动映射到标签身上

2.把网页内容当做对象来处理

3.document对象

  • 是DOM里的最大的一个对象
  • 所以它提供的属性和方法都是用来访问和操作网页内容的
  • 网页所有的内容都写在document里面

(3).获取DOM对象

1.选择匹配的第一个元素

1
document.querySelector('css选择器')
  • 参数:包含一个或多个有效的css选择器 字符串
  • 返回值:css选择器匹配的第一个元素,一个HTMLELEMENT对象,如果没有匹配,就返回为null

2.选择多个css选择器

1
document.querySelectorAll('css选择器 css选择器')
  • 参数:包含一个或多个有效的css选择器 字符串
  • 返回值:css选择器匹配的对象集合

得到的是一个伪数组

  • 有长度,有索引的数组
  • 但是没有pop(),push()等数组方法

要通过for循环获得里面的每一个对象

(4).操作元素内容

目标:修改元素的文本更换内容

DOM对象都是根据标签生成的,所以操作标签,本质上就是操作DOM对象

欲修改标签里面的内容:

  1. 对象.innerText属性
  2. 对象.innerHTML属性

1.innerText属性

  • 将文字内容添加/更新到任意标签位置
  • 显示纯文本,不解析标签
1
2
const app=document.querySelector('div')
app.innerText='div文字内容'

2.innerHTML属性

  • 将文本内容添加/更新到任意标签位置
  • 会解析标签,多标签建议使用模板字符
1
2
const app=document.querySelector('div')
app.innerHTML='div文字内容'

(5).操作元素属性

1.操作元素常用属性

​ 还可以通过.操作设置/修改标签元素属性,比如通过src更换图片

   常见的属性比如:href,title,src等
1
2
const app=document.querySelector('img')
app.title='更改标题显示'
2.操作元素样式属性

​ 还可以通过js设置/修改标签元素的样式属性

​ 比如通过轮播图小圆点自动更换颜色样式

​ 点击按钮可以滚动图片,这是移动的图片的位置left等等

  • 通过style属性操作css
    单个单个地修改,替换

语法:对象.style.样式属性=值

1
2
const app=document.querySelector('div')
app.style.width='1000px'
  • 操作类名(className)操作css
    有着覆盖的作用·

如果修改的样式比较多,直接通过style属性修改比较繁琐,这是就可以通过css类名的形式

1
2
const app=document.querySelector('div')
app.className='spp'//添加类名,class是个关键字,我们用className

由于class是关键字,所以使用className去代替

className是使用新值换旧值,如果需要添加一个类,需要保留之前的类名

  • 通过classList操作控制css
    可添加,删除,切换;不会影响之前的类名

为了解决className容易覆盖以前的类名,我们可以通过classList方式追加和删除类名

​ //通过classList添加

​ const div=document.querySelector(‘.app’)

​ div.classList.add(‘active’)

​ //追加类,不用加.,而且是字符串,追加括号里面的类

​ div.classList.remove(‘app’)

​ //删除类,不用加.,而且是字符串,删除括号里面的类

​ div.classList.toggle(‘active’)

​ //切换类,如果有对应的类名,就删掉,没有对应的类名,就添加上去

​ div.classList.contains(‘类名’)

​ //查找类

72333987828

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<!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>
.app
{
width: 200px;
height: 200px;
color: black;
margin: 200px auto;
}
.active
{
background-color: pink;
}
</style>
</head>
<body>
<div class="app">文字颜色</div>
<script>
const div=document.querySelector('.app')
//通过classList添加
div.classList.add('active')
//追加类,不用加.,而且是字符串,追加括号里面的类
div.classList.remove('app')
//删除类,不用加.,而且是字符串,删除括号里面的类
div.classList.toggle('active')
//切换类,如果有对应的类名,就删掉,没有对应的类名,就添加上去
</script>
</body>
</html>
  • 操作表单元素属性

    表单也可以像其他标签一样可以修改属性值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<!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>
<input type="text" value="电脑">
<script>
const name=document.querySelector('input')
console.log(name.value)//可以获取表单里面的值
console.log(name.innerHTML)//不可以获取表单里面的值
//直接得不到表单里面的值
name.value='pppppp'//设置表单里面的值
console.log(name.type)//输出为text(文本内容)
name.type='password'//将input的type改为password类型
</script>
</body>
</html>

​ 表单属性中添加就有效果,删除就没有效果,一律用布尔值来表示,如果 为true则表示添加了该属性,为false则表示移除了该属性

​ 比如有:dsiabled,checked,selected

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<!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>
<input type="checkbox" name="" id="">
<!-- <input type="text" checked> -->
<!-- 如果里面加了checked,就是表示已经勾选的状态,如果没有checked,则表示未勾选的状态 -->

<button>按钮</button>
<!-- <button disabled></button> -->
<!-- 如果button里面含有dsiabled,表示不禁用按钮 -->
<script>
const app=document.querySelector('input')
console.log(app.checked);
//如果上面的html中没有checked,则返回false,反之,则返回true
app.checked=true
app.checked='true'//也会运行成功,因为有着隐士转换为true,字符串非空即为true

const spp=document.querySelector('button')
console.log(spp.disabled);//默认为false,表示不禁用
spp.disabled=true//表示禁用,false表示不禁用
</script>
</body>
</html>
  • 自定义属性
  1. 标准属性

    ​ 标签自带的属性,比如:class,id,title等,可以直接使用点语法操作比如:disabled,checked,selected

  2. 自定义属性

    在html5中推出来的专门的data-自定义属性

    在标签上一律以dataset对象方式获取

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    <!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 class="app" data-ssmm="不清楚">测试的div</div>
    <script>
    const aaa=document.querySelector('div')
    console.log(aaa.dataset);//获取整个自定义的data的对象集合
    console.log(aaa.dataset.ssmm);//获取自定义的data-ssmm的内容
    </script>
    </body>
    </html>

(6).定时器-间歇函数

1.介绍

功能:如网页中每隔一段时间需要执行一段代码,不需要认为手动去操 作,使用定时器能重复执行代码

定时器函数可以开启和关闭定时器

如:网页中的倒计时

定时函数有两种

2.定时器的语法及使用

​ 开启定时器:

1
setInterval(函数,间隔时间)
  • 作用:每隔一段时间调用这个函数

  • 间隔时间单位为毫秒

    关闭定时器:

1
2
let 变量名=setInterval(函数名,间隔时间)
clearInterval(变量名)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<!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>
<script>
//开启定时器
// setInterval(函数,间隔时间)
setInterval(function () { document.write(123) }, 1000)
//可以用匿名函数
function app() {
document.write('每过一秒就打印一次')
}
setInterval(app, 1000)//函数名字不需要加括号
let number = setInterval(app, 1000)
document.write(number)//定时器返回的是一个id数字

// let 变量名=setInterval(函数名,间隔时间)
// clearInterval(变量名)
clearInterval(number)//关闭定时器
</script>
</body>

</html>

(7).事件监听

语法:

元素对象.addEventListener(‘事件类型’,要执行的函数)

三要素:

  1. 事件源:那个dom元素被触发了,要获取dom元素
  2. 事件类型:用什么方式触发,比如鼠标单击click,鼠标经过mouseover等
  3. 事件调用的函数:要做什么事

注意:事件类型要加引号

函数是点击之后再去执行,每次点击都会执行一次

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!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>点击会弹出对话框</button>
<script>
//点击会弹出一个对话框
const app=document.querySelector('button')
app.addEventListener('click',function(){alert('How are you!!!')})
</script>
</body>
</html>

列如关闭广告:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
<!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>
.box
{
margin: 100px auto;
width: 400px;
}
.box1
{
margin-top: 20px;
width: 400px;
height: 200px;
background-color: aqua;
position: relative;
}
.box2
{
width: 20px;
height: 20px;
position: absolute;
top: 0;
right: 0;
text-align: center;
background-color: pink;
}

</style>
</head>
<body>
<div class="box">
<span>点击右上角关闭广告</span>
<div class="box1">
<div class="box2">
6
</div>
</div>
</div>
<script>
const app=document.querySelector('.box1')//父级div
const spp=document.querySelector('.box2')//子级div
app.addEventListener('click',//当子级点击的时候
function(){
app.style.display='none'//父级消失,子级也一起消失
})
</script>
</body>
</html>

(例题)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
<!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>
.banner
{
margin:200px auto;
width: 500px;
height: 300px;
border: 1px solid #000;
/* background-color: pink; */
}
.strant
{
width: 500px;
height: 60px;
/* background-color: aqua; */
text-align: center;
line-height: 60px;
font-size: 24px;
font-weight: 16px;

}
.middle
{
padding-left: 20px;
line-height: 100px;
height: 100px;
font-size: 26px;
}
.middle .ooo
{
color: red;
}
.buttnn
{
align-items: center;
justify-content: space-evenly;
display: flex;
margin-top: 50px;
}
.left
{
line-height: 30px;
width: 90px;
height: 30px;
border: 1px solid #000;
text-align: center;
}
.right
{
line-height: 30px;
width: 90px;
height: 30px;
border: 1px solid #000;
text-align: center;
}
</style>
</head>
<body>
<div class="banner">
<div class="strant">
随机问答
</div>
<div class="middle">
<span>名字是:</span>
<span class="ooo">这里显示名字</span>
</div>
<div class="buttnn">
<button class="left">开始</button>
<button class="right">结束</button>
</div>
</div>
<script>
let number
let random
const arr=['汤卸','罗鑫','老王','大神','超神']
const app=document.querySelector('.left')
const spp=document.querySelector('.ooo')
const end=document.querySelector('.right')
app.addEventListener('click',function(){
number=setInterval(function(){
random=Math.floor(Math.random()*arr.length)
spp.innerHTML=arr[random]},90)

//如果数组中元素只有一个,那么就禁用按钮
if(arr.length===1)
{
app.disabled=true
end.disabled=true
}
})
end.addEventListener('click',function(){
clearInterval(number)
//删除结束的那个元素
arr.splice(random,1)
})
</script>
</body>
</html>

最早的事件监听方法:

事件源.on事件=function(){}

现在的事件监听的方法:

事件源.addEventListener(事件,事件处理函数)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<!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>
按钮
</button>
<script>
const app = document.querySelector('button')
app.onclick = function () { alert('这是第一种的写法!!!!') }
app.onclick = function () { alert('这是第一种的写法的复制版!!!!') }
//会覆盖第一个事件监听
app.addEventListener('click', function () {
alert('这是第二钟写法!!!!!')
})
app.addEventListener('click', function () {
alert('这是第二钟写法!!!!!')
})
//不会覆盖自己同种类型的第一个时间监听
</script>
</body>

</html>

(8).事件类型

1.鼠标事件(鼠标触发)

click 鼠标点击

mouseenter 鼠标经过

mouseleave 鼠标离开

2.焦点事件(表单或得光标)

focus 或得焦点

blur 失去焦点

3.键盘事件(键盘触发)

keydown 键盘按下触发

keyup 键盘抬起触发

4.文本事件(表单输入触发)

input 用户输入事件

5.change事件

当输入的内容发生改变的时候,才会触发change事件

(9).事件对象

事件对象就是个对象,这个对象里有事件触发时的相关信息;

事件对象在事件绑定的回调函数的第一个参数就是事件对象;

(10).环境对象

环境对象指的就是特殊的this变量,他代表的就是当前函数运行时所处的环境

每个函数内部独有this

72180564582

(11).回调函数

如果将·函数A作为参数传递给函数B时,我们称函数A为回调函数

(12).事件流

72189208148

事件流的两个阶段:事件捕获,事件冒泡;

事件流指的是指的是事件完整过程中的流动路线

1.事件捕获

从大的往下查找,从大到小

72196419887

72196435312

2.事件冒泡

从小的到大的查找,从小到大(注意的是,事件的类型必须要相同)

72196443253

3.阻止冒泡

72196468712

72196471501

4.事件解绑

72196488275

72196490230

72196500952

72196528748

(13).事件委托

72198070372

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<!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>
<ul>
<li>第一个数字</li>
<li>第二个数字</li>
<li>第三个数字</li>
<li>第四个数字</li>
<p>我是p标签,不是li标签</p>
</ul>
<script>
let app=document.querySelector('ul')
app.addEventListener('click',function(e){
// this.style.color='red';
//这种方法不对,全部都会变为红色,目标只是让li标签变为红色

// e.target.style.color='red'
//这个方法还是错的,p标签也变为了红色,但是目标只让li标签变为红色

if(e.target.tagName==='LI')//注意的是,这里的LI必须为大写
{
e.target.style.color='red'
}
//这个才是正确的答案
})
</script>
</body>
</html>

72198215230

(14).阻止冒泡

72206982457

72207006596

(15).页面加载事件

72207059880

72207079756

(16).元素滚动事件

72207092872

72207905126

72207909452

72207927487

可以写页面的打开所在的位置;可以写其位置

72207938006

(17).页面尺寸事件

72221507397

72221523981

(17).元素尺寸于位置-尺寸

72221568222

72221700831

72235005109

72235007755

(18).日期对象

1.简介
1
2
3
4
5
6
7
<script>
let app=new Date()//获取当前时间
document.write(app)
document.write('<br>')
let spp=new Date('2020-5-20')//获取指定的时间
document.write(spp)
</script>

72239497313

2.方法

72259213574

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<!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: 40px;
background-color: aqua;
text-align: center;
line-height: 40px;
}
</style>
</head>
<body>
<div></div>
<script>
let spp=document.querySelector('div')
function app()
{
let date=new Date()
return `今天是${date.getFullYear()}${date.getMonth()+1}${date.getDate()}${date.getHours()}:${date.getMinutes()}`
}
spp.innerHTML=app()
</script>
</body>
</html>

表示时间的另一种方法:(直接表示时间)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=
, initial-scale=1.0">
<title>Document</title>
<style>
div
{
width: 200px;
height: 40px;
background-color: aqua;
text-align: center;
line-height: 40px;
}
</style>
</head>
<body>
<div></div>
<script>
let app=document.querySelector('div')
let date=new Date()
app.innerHTML=date.toLocaleDateString()//2024/8/2
app.innerHTML=date.toLocaleString()//2024/8/2 下午10:19:11
app.innerHTML=date.toLocaleTimeString()//下午10:20:09
</script>
</body>
</html>

72362766791

3.时间戳:

72260880450

72260926196

72260939470

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
.countdown {
width: 240px;
height: 305px;
text-align: center;
line-height: 1;
color: #fff;
background-color: brown;
/* background-size: 240px; */
/* float: left; */
overflow: hidden;
}

.countdown .next {
font-size: 16px;
margin: 25px 0 14px;
}

.countdown .title {
font-size: 33px;
}

.countdown .tips {
margin-top: 80px;
font-size: 23px;
}

.countdown small {
font-size: 17px;
}

.countdown .clock {
width: 142px;
margin: 18px auto 0;
overflow: hidden;
}

.countdown .clock span,
.countdown .clock i {
display: block;
text-align: center;
line-height: 34px;
font-size: 23px;
float: left;
}

.countdown .clock span {
width: 34px;
height: 34px;
border-radius: 2px;
background-color: #303430;
}

.countdown .clock i {
width: 20px;
font-style: normal;
}
</style>
</head>

<body>
<div class="countdown">
<p class="next">今天是2222年2月22日</p>
<p class="title">下班倒计时</p>
<p class="clock">
<span id="hour">00</span>
<i>:</i>
<span id="minutes">25</span>
<i>:</i>
<span id="scond">20</span>
</p>
<p class="tips">18:30:00下课</p>
</div>
<script>
function wps()
{
let now=+new Date()
let last=+new Date('2024-8-3 23:59:59')
let app=(last-now)/1000
let h=parseInt(app/60/60%24)
let f=parseInt(app/60%60)
let s=parseInt(app%60)
let hour=document.querySelector('#hour')
let minutes=document.querySelector('#minutes')
let scond=document.querySelector('#scond')
hour.innerHTML=h
minutes.innerHTML=f
scond.innerHTML=s
}
setInterval(wps,1000)
</script>
</body>

</html>

(19).DOM节点操作

1.dom节点

72267949911

72267949911

2.查找节点

72267949911

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!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 class="father">
<div class="son"></div>
</div>
<script>
let son=document.querySelector('.son')
console.log(son.parentNode)//返回dom对象
//还可以是父节点的父节点son.parentNode.parentNode
</script>
</body>
</html>

72267949911

72267949911

72267949911

3.增加节点

72267949911

72267949911

72267949911

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<!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>
<ul>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
<script>
let app=document.querySelector('ul')
console.log( app.children);//获取的是全部的li标签
let opp=document.querySelector('ul li:nth-child(2)')
console.log(opp.nextElementSibling);//下一个元素
console.log(opp.previousElementSibling);//上一个元素
let li=document.createElement('li')
li.innerHTML='我是小li'
app.appendChild(li)//追加到父元素的最后一个位置上
// 父级元素.insertBefore(插入的元素,放到哪个元素的前面)
let li1=document.createElement('li')
li1.innerHTML='我是第二个小li'
app.insertBefore(li1,ul.children[0])
</script>
</body>
</html>
4.删除节点

72267949911

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!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>
<ul>
<li></li>
</ul>
<script>
let app=document.querySelector('ul')
app.removeChild(app.children[0])//删除节点必须为父级元素删除字级
</script>
</body>
</html>

(20).M端事件

72267949911

(21).插件

72267949911

4.BOM

(1).简介

72286607154

72286615031

(2).定时器–延时函数

72286683691

72286693053

//注意:不能再定时器的内部对定时器进行删除,因为定时器还在运行,不能删除定时器,就是对定时器进行clear的操作,但是可以对定时器赋值为null的操作

1
2
3
4
<script>
let timee=setTimeout(function(){alert('时间到了!!!')},2000)
// clearTimeout(timee)//可以用来清理定时器
</script>

(3).js执行机制

72286735083

72286741859

72286755423

72286768606

72286785818

(4).Window对象

1.location对象

72290832368

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<!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>

</style>
</head>
<body>
<div>
<a href="http://www.3sb8.com">还有<span>5</span>秒马上跳转到指定页面</a>
</div>
<script>
let app=document.querySelector('a')
let s=5
let time= setInterval(function(){
s--
app.innerHTML=`还有<span>${s}</span>秒马上跳转到指定页面`
if(s===0)
{
clearInterval(time)
location.href='http://www.3sb8.com'
}
},1000)
</script>
</body>
</html>

72290941634

72290954534

72290957920

2.navigator对象

72290969557

3.histroy对象

72291091626

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<!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 class="s1">前进</button>
<button class="s2">后退</button>
<script>
let back=document.querySelector('.s2')
let forward=document.querySelector('.s1')
back.addEventListener('click',function(){
window.history.back()//后退一步
})
forward.addEventListener('click',function(){
history.forward()//前进一步
})
</script>
</body>
</html>

(5).本地存储

1介绍

72291163443

2.分类(两种)

72291184839

72291434319

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!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>
<script>
//采用键值对的写法,与map的写法相类似!!!
localStorage.setItem('name', '第一次存储信息')//存储信息
console.log(localStorage.getItem('name'))//获取信息
//删除本地存储,只用删除名字
// localStorage.removeItem('name')

localStorage.setItem('age', 19)
console.log(localStorage.getItem('age'))//得到的是一个字符串,并不是一个数字
//注意存进去的数字会变成字符串,注意!!!
</script>
</body>

</html>

72291491027

这个的存储方式的写法和上面的写法完全一样!!!

72291493932

//注意的是,在存储的写法中,键(key)要加引号,其中的值存储进去会转化为字符串

3.存储复杂数据类型

在对于像对象这样的复杂数据类型中,不能直接存储

//下面的这种写法就是错误的写法!!!!!!

1
2
3
4
5
6
7
8
9
10
<script>//错误的写法,不不正确的写法
let object=
{
name:'我是你大爷',
age:90,
gender:'man'
}
localStorage.setItem('obj',objeat)
console.log(localStorage.getItem('obj'));
</script>

//复杂数据类型必须转换位JSON字符串存储

72291602871

//这个才是正确的存储方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<!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>
<script>
let object=
{
name:'我是你大爷',
age:90,
gender:'man'
}
localStorage.setItem('obj',JSON.stringify(object))//复杂数据类型存储必须转换为JSON字符串存储
console.log(localStorage.getItem('obj'));
</script>
</body>
</html>

当把要拿来用是,要把JSON字符串转换为对象,这个时候就用到JSON.parse()这个方法

72291892210

72303972250

5.正则表达式

(1).简介

72312030366

72312045292

72312048014

(2). 语法

72312085629

72312103628

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!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>
<script>
let app='前端前端!!!天天要学前端,啊啊啊啊啊!!!'
let s1=/前端/
let s2=s1.test(app)
document.write(s2)//最后返回true
//如果没有相应匹配的,那么返回的是false
</script>
</body>
</html>

72312147671

注意的是这个返回的是一个数组

72312160535

(3).元字符

72312849496

72312859116

72312864931

1.边界符

72312896998

1
2
3
4
5
<script>
console.log(/汗/.test('我出汗了!!!'))//true
console.log(/^汗/.test('我出汗了!!!'))//false
console.log(/汗$/.test('出了好多汗'))//true
</script>
2.量词

72316240809

//逗号左右两侧千万不能出现空格

72316379409

1
2
3
4
5
6
7
8
<script>
console.log(/^含*$/.test('含含含'))//true
console.log(/^含+$/.test('含含含含'))//true
console.log(/^含+$/.test(''))//false
console.log(/^含?$/.test('含含含'))//false
console.log(/^含?$/.test(''))//true
console.log(/^含?$/.test('含'))//true
</script>
3.字符类

72316398746

在括号里的只能出现一次,只能选一次

72316407610

72316434058

72316445950

72316448476

72316450154

72317139478

(4).修饰符

72317146170

1
2
3
4
<script>
console.log(/java/.test('java'));//true
console.log(/java/i.test('JAVA'));//true
</script>

72317390557

1
2
3
4
5
6
7
<script>
let app='前端是一门编程语言,学完之后会有很高的工资!!!'
let spp=app.replace(/前端/ ,'java')
console.log(spp);
//返回值:
// java是一门编程语言,学完之后会有很高的工资!!!
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<!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>
button
{
width: 60px;
height: 20px;
}
</style>
</head>
<body>
<textarea name="" id="" cols="30" rows="10"></textarea>
<button></button>
<div></div>
<script>
let textarea=document.querySelector('textarea')
let button=document.querySelector('button')
let div=document.querySelector('div')
button.addEventListener('click',function(){
div.innerHTML=textarea.value.replace(/好香|好看/g,'**')
textarea.value=''
})
</script>
</body>
</html>

4.DOM大总结

(1).获取元素

  1. document对象 - 基础起点,所有DOM操作的根对象。

  2. getElementsByTagName() - 方法用于获取文档中所有具有指定标签名的元素集合(HTMLCollection)。

    //获取标签名,在括号里要加入标签名

  3. getElementsByClassName() - 方法用于获取文档中所有具有指定类名的元素集合(HTMLCollection)。

    //class类名……

  4. getElementsByName() - (注意:图片文字中未直接显示,但根据图片信息推测存在)方法用于获取文档中所有具有指定name属性的元素集合(NodeList)。

    //name名……

  5. getElementById() - (注意:图片文字中拼写错误为getElementByld)方法用于获取文档中唯一具有指定ID的元素。

    //id名……

  6. querySelector() - 方法返回文档中匹配指定CSS选择器的第一个元素。

    //只会返回第一个元素的,可以是.类名;#id名

  7. querySelectorAll() - 方法返回文档中所有匹配指定CSS选择器的元素集合(NodeList)。

    //可以获取多个

(2).创建元素

document创建元素

document.createElement()

//创建标签

document.createTextNode()

//创建文本内容

createAttribute()

//创建相应的属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<body>
<p id='sss'></p>

<script>
let app=document.createElement('div')
// console.log(app)
let content=document.createTextNode('我是文本内容')
//appendChild:将内容或者子元素放到容器中
app.appendChild(content)
// console.log(app);
let id=document.createAttribute('id')
id.value='root'
app.setAttributeNode(id)
document.write(app)

let s1=document.getElementById('sss')
s1.appendChild(app)
</script>
</body>

Element获取元素位置

7215774409272157772035

css操作

72157781336

72160789527

72160796730

DOM事件:

72160841882

1.HTML事件处理:

72160873156

2.DOM0事件:

72181110615

3.DOM2事件:

72181073778

事件类型之鼠标事件:

72181116273

Event事件对象:

72181131336

72181136883

72181142101

72181172286

事件对像方法:

72181181148

事件类型之键盘事件:

72181191104

事件类型之表单事件:

72181203447

72181205898

72181214107

72181216558

72181223400

72181224991

72181234047

事件代理:

72181270819

72181278689

定时器:

72181289034

这个定时器只会发生一次,不会发生第二次

72181312732

对于复选框:

72187775400

四.javascript进阶

1.作用域

(1).局部作用域

1.函数作用域

在函数内部申明的变量只能在函数内部进行访问,在函数外部无法进行直接访问

72342365202

2.块作用域

在javascript中使用{}包裹的代码称为代码块,代码内部申明的变量外部无法被访问(也由可能被访问到)

var申明的不会产生块作用域

72342386737

(2).全局作用域

在script标签和.js文件就是所谓的全局作用域,在全局作用域中申明的变量在函数内部也可以被访问到

72342405697

(3).作用域链

72342442484

2.垃圾回收机制

72342460048

72342466391

(1).引用计数法

72342541857

72342539557

(2).标记清除法

72342551797

3.闭包

72342565899

闭包可以实现在函数外部可以使用函数内部的变量

72342620791

闭包可以实现一个数据的私有,不能被外界所修改,保证了数据的安全

闭包可能会导致内存泄露

72342906773

4.函数进阶

(1).函数提升

//函数提升和C++的函数声明的提升一样,把函数申明提升到最前面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<script>
app()
var s1=function app()
{
console.log('函数表达式');
}
//像函数表达式一样,函数表达式会提升变量,不会提升函数申明
// 函数申明表达式必须先申明和赋值否则会报错

fun()
function fun()
{
console.log('这是正常的函数提升');
}
</script>

72342974227

(2).函数参数

1.动态参数

arguments是函数内部内置的伪数组变量,它包含了调用函数时传入的所用实参

72342998481

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<script>
function app()
{
//动态参数可以传入多个参数
let ans=0
for(let i=0;i<arguments.length;i++)
{
ans+=arguments[i]
}
console.log(`这几个数字的加起来的和为${ans}`);
}
app(12,23,24,23,54,324,32)
app(12,23,234,23)
</script>

72343071360

2.剩余参数

72343100374

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<script>
function getsum(...arr)//这里的arr可以随便写一个变量名字,不只是只可以写arr
{
let ans=-0
for(let i=0;i<arr.length;i++)
{
ans+=arr[i]
}
console.log(ans);
}
getsum(12,23,2,1,23,12,231)

//还有另一种写法
function sum(a,b,c,...app)//这里的a,b,c可以随便写,这里表示的app是真得数组,其中的app数组获取的是除了开头的前3个参数的一个数组
{
console.log(`这个a=${a}`);
console.log(`这个b=${b}`);
console.log(`这个c=${c}`);
console.log(`这个数组=${app}`);
}
sum(12,123,12,3,214,23,23)
</script>

剩余参数与动态参数的最大区别在于动态参数是伪数组,而剩余参数是真数组

3.展开运算符

展开运算符:在数组中使用,将数组展开

剩余参数:在函数参数使用,得到的是真数组

(3).箭头函数

1.基本语法

72344689661

72344693039

72344693943

72344703985

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<script>
//普通函数
let fun1=function()
{
console.log('这是普通函数');
}

//箭头函数
let fun2=()=>
{
console.log('这是箭头函数');
}

//当只有一个参数的时候,小括号可以被省略
let fun3=x=>
{
console.log('这也是箭头函数');
console.log(`其中这个参数是${x}`);
}
fun3(23455)

//当只有一行代码的时候还可以省略大括号!!!
let fun4=x=>console.log(`这个可以省略大括号,其中的值为${x}`);
fun4(123456789)

//只有一行代码的时候,还可以省略return
let fun5=x=>x+x+x*4
console.log(fun5(23));

//箭头函数可以返回一个对象
let fun6=(name)=>({username:name})//返回一个对象
fun6('老刘')
console.log(fun6('老刘'));
</script>

72344680568

箭头函数里没有arguments动态参数

2.箭头函数this

72344756899

72344902580

72344907322

1
2
3
4
5
6
7
8
9
10
11
<script>
//箭头函数的this指向他的上一级
let app=
{
name:'老刘',
getname:()=>{
console.log(this);
}
}
app.getname()//返回的是Window
</script>

5.解构赋值

(1).数组解构

72345432111

1
2
3
4
5
6
7
<script>
let arr=[122,34342,3423]
let [max,min,app]=arr
console.log(max);
console.log(min);
console.log(app);
</script>

72345505563

//一定要加分号;

1
2
3
4
5
6
7
8
9
<script>
//数组解构
// 可以用来交换两个变量
let a=23
let b=12;
console.log(`原本的a=${a},原本的b=${b}`);
[a,b]=[b,a]
console.log(`现在的a=${a},现在的b=${b}`);
</script>

剩余参数解决变量少,单元值多的情况

1
2
3
4
5
6
<script>
let [a,b,...arr]=[12,23,34,45,32323,12]//用剩余参数解决变量少,单元值多的情况
console.log(a);
console.log(b);
console.log(arr);//真数组
</script>

72345683620

72345687482

//也可以按需导入赋值

72347814909

(2).对象解构

1.对象

72347890126

1
2
3
4
5
6
7
8
9
10
11
12
<script>
//解构对象
let obj=
{
name:'老刘',
age:18
}
let {name,age}= {//其中的第一个大括号中的name与age都是不能改变的,要与后面的对象中的相对应
name:'老刘',
age:18
}
</script>

//对于如果在其上面有定义的属性与对象中的名字相同的情况,可以用别名的方式

1
2
3
4
5
6
7
8
9
10
11
12
13
<script>
//解构对象
let name='拉拉队员'
let obj=
{
name:'老刘',
age:18
}
let {name:username,age}={//当上面有定义的与对象中的名字相一致的时候,这时就可以起别名的方式来解决
name:'老刘',
age:18
}
</script>
2.数组对象

72348017072

1
2
3
4
5
6
7
8
9
10
11
12
<script>
let app=[{
name:'老刘',
age:234,
sex:'man'
}]
let [{name,age,sex}]=[{
name:'老刘',
age:234,
sex:'man'
}]//与对象的语法大相径庭
</script>
3.对象中有对象

当对象中有对象的时候,要具体表明是哪一个对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<script>
let pig=
{
name:'佩奇',
family:
{
mother:'妈',
father:'巴',
sister:"你"
},
age:19
}
let {name,family:{mother,father,sister},age}=pig//注意的是,这里的对象里面的对象要标明具体是哪一个对象,列如:family: 这样的格式
console.log(name);
console.log(mother);
console.log(father);
console.log(age);
</script>

对于其他的情况,后面的处理与前面的处理相类似

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<script>
let app=
{
code:12,
family:22,
date:
[
{
id:1,
title:'ass'
},
{
id:2,
title:'wee'
}
]
}

function gender({date})//直接解构过来用就OK了//在这里也可以直接用别人进行对date起别名
{
console.log(date);
}
gender(app)
</script>

!!!在一个对象中,想要哪一个属性就直接解构过来用就可以了!!!

案例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>商品渲染</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}

.list {
width: 990px;
margin: 0 auto;
display: flex;
flex-wrap: wrap;
}

.item {
width: 240px;
margin-left: 10px;
padding: 20px 30px;
transition: all .5s;
margin-bottom: 20px;
}npx

.item:nth-child(4n) {
margin-left: 0;
}

.item:hover {
box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.2);
transform: translate3d(0, -4px, 0);
cursor: pointer;
}

.item img {
width: 100%;
}

.item .name {
font-size: 18px;
margin-bottom: 10px;
color: #666;
}

.item .price {
font-size: 22px;
color: firebrick;
}

.item .price::before {
content: "¥";
font-size: 14px;
}

.filter {
display: flex;
width: 990px;
margin: 0 auto;
padding: 50px 30px;
}

.filter a {
padding: 10px 20px;
background: #f5f5f5;
color: #666;
text-decoration: none;
margin-right: 20px;
}

.filter a:active,
.filter a:focus {
background: #05943c;
color: #fff;
}
</style>
</head>

<body>
<div class="filter">
<a data-index="1" href="javascript:;">0-100元</a>
<a data-index="2" href="javascript:;">100-300元</a>
<a data-index="3" href="javascript:;">300元以上</a>
<a href="javascript:;">全部区间</a>
</div>
<div class="list">
<!-- <div class="item">
<img src="" alt="">
<p class="name"></p>
<p class="price"></p>
</div> -->
</div>
<script>
// 2. 初始化数据
const goodsList = [
{
id: '4001172',
name: '称心如意手摇咖啡磨豆机咖啡豆研磨机',
price: '289.00',
picture: 'https://yanxuan-item.nosdn.127.net/84a59ff9c58a77032564e61f716846d6.jpg',
},
{
id: '4001594',
name: '日式黑陶功夫茶组双侧把茶具礼盒装',
price: '288.00',
picture: 'https://yanxuan-item.nosdn.127.net/3346b7b92f9563c7a7e24c7ead883f18.jpg',
},
{
id: '4001009',
name: '竹制干泡茶盘正方形沥水茶台品茶盘',
price: '109.00',
picture: 'https://yanxuan-item.nosdn.127.net/2d942d6bc94f1e230763e1a5a3b379e1.png',
},
{
id: '4001874',
name: '古法温酒汝瓷酒具套装白酒杯莲花温酒器',
price: '488.00',
picture: 'https://yanxuan-item.nosdn.127.net/44e51622800e4fceb6bee8e616da85fd.png',
},
{
id: '4001649',
name: '大师监制龙泉青瓷茶叶罐',
price: '139.00',
picture: 'https://yanxuan-item.nosdn.127.net/4356c9fc150753775fe56b465314f1eb.png',
},
{
id: '3997185',
name: '与众不同的口感汝瓷白酒杯套组1壶4杯',
price: '108.00',
picture: 'https://yanxuan-item.nosdn.127.net/8e21c794dfd3a4e8573273ddae50bce2.jpg',
},
{
id: '3997403',
name: '手工吹制更厚实白酒杯壶套装6壶6杯',
price: '99.00',
picture: 'https://yanxuan-item.nosdn.127.net/af2371a65f60bce152a61fc22745ff3f.jpg',
},
{
id: '3998274',
name: '德国百年工艺高端水晶玻璃红酒杯2支装',
price: '139.00',
picture: 'https://yanxuan-item.nosdn.127.net/8896b897b3ec6639bbd1134d66b9715c.jpg',
},
]
function gender(arr)
{
let str=''
arr.forEach(element => {
let {name,price,picture}=element
str+=`
<div class="item">
<img src=${picture} alt="">
<p class="name">${name}</p>
<p class="price">${price}</p>
</div>
`
});
document.querySelector('.list').innerHTML=str
}
document.querySelector('.filter').addEventListener('click',e=>{
let {tagName,dataset}=e.target
if(tagName==='A')
{
let arr=goodsList
if(dataset.index==='1'){
arr=goodsList.filter(app=>app.price>0&&app.price<=100)
}else if(dataset.index==='2'){
arr=goodsList.filter(app=>app.price>100&&app.price<=300)
}else if(dataset.index==='3'){
arr=goodsList.filter(app=>app.price>300)
}
gender(arr)
}
})
</script>
</body>

</html>

6.深入对象

72351835077

1
2
3
4
5
6
7
8
9
<script>
let obj=//第一钟创建对象的方法
{
name:1233
//.....
}
let obj1=new Object({name:3123})//第二种创建对象的方法
//第三种,利用构造函数创建对象
</script>

(1).构造函数

72351877602

72351900656

//注意:构造函数的首字母规定要大写

72352019824

(2). 实例成员&静态成员

72352101760

实例成员包括实例属性和实例方法

就是实例化了的对象中的属性和方法

72352122597

静态成员指的是未实例化的对象得属性和方法

1
2
3
4
5
6
7
8
9
10
11
12
13
<script>
//静态成员
function Pig(name)
{
this.name=name
}
Pig.eye=2
Pig.work=function(){
console.log('peson can work!!!');
}
console.log(Pig.eye);
console.log(Pig.work());
</script>

7.内置构造函数

72353141734

(1).Object方法

1.Object.values与Object.keys

72353222156

72353219800

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<script>
let app=
{
name:'Alice',
age:19
}
console.log(Object.keys(app));
console.log(Object.values(app));
Object.assign(app,{gender:'feman'})
let ooo=
{
arm:3
}
Object.assign(app,ooo)
console.log(app);
</script>
2.Object.assign()方法

72362412625

1
2
3
4
5
6
7
8
9
10
const target = { a: 1, b: 2 };
const source = { b: 4, c: 5 };

const returnedTarget = Object.assign(target, source);

console.log(target);
// Expected output: Object { a: 1, b: 4, c: 5 }

console.log(returnedTarget === target);
// Expected output: true

(2).Array方法

72353408485

1.reduce方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<script>
let arr=[12,3,1,312,1,2312,3,1243,1231]//没有初始值得情况下会出现的结果
let ans1=arr.reduce(function(a,b){
return a+b
})
console.log(ans1);
//有初始值得情况下
let ans2=arr.reduce(function(a,b){
return a+b
},10000)
console.log(ans2);
//用箭头函数写的情况为
let ans3=arr.reduce((a,b)=>a+b,1000000)//其中的a和b可以随便写
console.log(ans3);
</script>

对象中的数字相加

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<script>
//在对象中的属性值相加时
let app=
[
{
nsme:'ALICE',
salary:1200
},
{
nsme:'alice',
salary:12324
},
{
nsme:'Alice',
salary:12342
}
]
let ans=app.reduce((a,b)=>a+b.salary,0)//需要注意的是,reduce()的第二个参数必须要有一个数,如果没有的话,则会报错,因为加的第一个数将会是对象,但是对象不能相加
console.log(ans);
</script>
2.其他方法

72353722893

find函数,如果在数组中使用,那么返回的是被找到的符合条件的第一个值,如果是在数组对象中使用,那么返回的将是满足条件的所有对象对象

1
2
3
4
5
<script>
let app=[12,23,4,21,312,412,3,1231]
let ans=app.find(item=>item>30)
console.log(ans);
</script>

every函数,与上面函数语法都相类似

1
2
3
4
5
<script>
let app=[12,23,4,21,312,412,3,1231]
let ans=app.every(item=>item>30)
console.log(ans);//false
</script>

some函数与上面函数的语法都很相类似

3.如何将真数组转化为伪数组

Array.form(伪数组)//将伪数组转化为真数组

1
2
3
4
5
6
7
8
9
10
11
12
13
<body>
<ul>
<li></li>
<li></li>
<li></li>
</ul>
<script>
let li=document.querySelectorAll('ul li')
console.log(li);
let li1=Array.from(li)
console.log(li1);
</script>
</body>

(3).String方法

72354080502

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<script>
//string的split方法 作用是将字符串转化为数组 与join的数组转化为字符串相反
let arr='pink,lalala,nonono'
let arr1=arr.split(',')//得到的是一个数组[pink,lalala,nonono]
console.log(arr1);//其中的分隔符可以改
//返回的是一个数组

//string的substring 作用是字符串的截取
let str='今年不用做核算精测了'//我故意写错的
console.log(str.substring(5));//如果只有一个数字,那么从这个数字一直截取到最后的自符
console.log(str.substring(5,7));//这个的截取范围是左边是闭合的,右边是开的
//返回的是字符串

//string的startsWith方法 作用是检查字符串开头是否以某个字符串开头,或者指定位置开始
let app='检查是否开头的是不是真的!!!'
console.log(app.startsWith('检查'));//true
console.log(app.startsWith('是否'));//false
console.log(app.startsWith('开头',4));//true
//返回的是true或者false

//string的includes方法 作用是检查字符串中是否含有某个字符或者某个字符串
let arr2='看看这里面是否含有某个字符或者字符串'
console.log(arr2.includes('里面'));//true
console.log(arr2.includes('看看', 3));//false
//返回的是true或者false
</script>

(4).Number方法

1.toFixed()

72355196854

8.深入面向对象

72359490575

72359499186

javascript是通过构造函数来实现面向对象的封装

javascript通过构造函数的面向对象会产生内存浪费的问题

(1).原型

72359587955

构造函数和原型对象中的this都指向实例化的对象

1
2
3
4
5
6
7
8
9
10
11
<script>
let arr=[1,313,1,1,31,2,1]
//因为arr可以看成let arr = new Array(1,313,1,1,31,2,1)
// 所以可以使用共享
Array.prototype.max=function()
{
// return Math.max(...arr)
return Math.max(...this)//因为this指向的是实例化的对象
}
console.log(arr.max());//这样就可以用来封装方法
</script>

(2).constructor属性

72359699276

72359724818

constructor属性的作用是指向该原型对象的构造函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<script>
function Star(name)
{
this.name=name
}
Star.prototype=//这样做的话就会覆盖了整个Star.prototype,所以constructor会被覆盖掉
{
sing:function(){
console.log('man'
);
}
}
//如何恢复constructor:
Star.prototype=
{
constructor:Star,
sing:function(){
console.log('man'
);
}
}//这样做的话,就能够恢复constructor
</script>

(3).对象原型

72359802257

72359814595

对象原型__proto__指向构造函数的原型对象

1
2
3
4
5
6
<script>
function App(){}
let cpp=new App()
//对象原型__proto__指向函数的原型对象
console.log(cpp.__proto__===App.prototype);//true
</script>

72359892528

(4).原型继承

//这种写法是错误的写法,不是真正的语法写法,这里只是示例

72360052993

72360055680

//这种继承会有缺点,就是两个或者多个对象对共享的对象prototype进行一个属性的添加或者减少时(这里只想对这个单独的对象进行修改,属于自己独有的属性),但是这样的话,将会对整个共享的对象prototype进行了修改,这样是我们不愿看到的结果,这也是他其中的一个缺点

//下面的这个方法是正确的写法,创建一个新的构造函数,这个构造函数内部包括的就是需要继承的东西,然后通过new 构造函数名()的形式对其他构造函数的赋值,记得后面还有进行对constructor的赋值,让他返回原本的属性不变,这样的写法保证了对继承时的独立性,一个构造函数的修改不会影响到其他的属性与方法,相比其上面的写法,这种写法是正确的,上面的那个写法就是会影响到其他对象的属形与方法,达不到预期的真正效果!!!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<script>//原型继承
function total()//公共的部分
{
this.person='people',
this.eye=2
}
function student()
{
this.time=5
}
function socialperson()
{
this.time=7
}
student.prototype=new total()
student.prototype.constructor=student
student.prototype.spead='time'
let a1=new student()

socialperson.prototype=new total()
socialperson.prototype.constructor=socialperson
let a2=new socialperson()

console.log(a1);
console.log(a2);
</script>

(5).原型链

72360475397

72360590959

instanceof的说明及其用法

1.instanceof方法

instanceof运算符用来检测 是否存在于参数 的原型链上。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// 定义构造函数
function C() {}
function D() {}

var o = new C();

o instanceof C; // true,因为 Object.getPrototypeOf(o) === C.prototype

o instanceof D; // false,因为 D.prototype 不在 o 的原型链上

o instanceof Object; // true,因为 Object.prototype.isPrototypeOf(o) 返回 true
C.prototype instanceof Object; // true,同上

C.prototype = {};
var o2 = new C();

o2 instanceof C; // true

o instanceof C; // false,C.prototype 指向了一个空对象,这个空对象不在 o 的原型链上。

D.prototype = new C(); // 继承
var o3 = new D();
o3 instanceof D; // true
o3 instanceof C; // true 因为 C.prototype 现在在 o3 的原型链上

9.深浅拷贝

(1).浅拷贝

拷贝的是地址

72362501217

1
2
3
4
5
6
7
8
9
10
11
<script>
let obj=
{
age:12
}
let app={...obj}
console.log(app.age);
app.age=1444
console.log(app.age);
console.log(obj.age);
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<script>
let app={
name:'lalala',
sss:{
age:19
}
}
let spp={}
Object.assign(spp,app)
spp.name='wuwuwu'
console.log(spp);
console.log(app);//简单数据可以进行拷贝

spp.sss.age=100
console.log(spp);
console.log(app);//这种浅拷贝不能拷贝对象中的对象,复杂的不能进行拷贝
</script>

72362595256

72362618831

(2).深拷贝

深拷贝有3钟方式:

72362628624

1.通过递归实现深拷贝

72362653160

1
2
3
4
5
6
7
8
<script>
function gettime()
{
document.querySelector('div').innerHTML=new Date().toLocaleString()
setTimeout(gettime,1000)
}
gettime()//递归函数
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<script>
let obj={
name:'www',
things:['123','133','422'],
app:{
age:12,
sex:'man'
}
}
function deepcopy(newobj,oldobj)
{
for(let i in oldobj)
{//先处理数组,在处理对象,因为万物皆对象,数组也是对象的一类,而且对象与数组的处理方式不一样,要先处理数组
if(oldobj instanceof Array){
newobj[i]=[]
deepcopy(newobj[i],oldobj[i])
}else if(oldobj instanceof Object)
{
newobj[i]={}
deepcopy(newobj[i],oldobj[i])
}else{
newobj[i]=oldobj[i]
}
}
}
let dpp={}
deepcopy(dpp,obj)
console.log(dpp);
dpp.app.age=123456789
console.log(dpp);
console.log(obj);
</script>
2.利用js库的lodash里面的_.clooneDeep()

递归拷贝

3.利用JSON字符串

想转化为字符串,再转化为原来的对象实现深拷贝

JSON.stringify(obj)转化为JSON字符串

JSON.parse(JSON.stringify(obj))再将其转化为原来的对象,赋值给新的一个对象

72368850151

10.异常处理

(1).throw抛日常

72369001465

1
2
3
<script>
throw "用户没有传递参数进来"
</script>
1
2
3
<script>
throw new Error('警告,错误!!!')
</script>

72369029380

72369032082

(2).try/catch捕获错误信息

72369097723

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<script>
function fun()
{
try{
//可能会发生错误的代码,写在try里面
let app=document.querySelector('div')
app.innerHTML='lalalalal'
}catch(errr){//用于拦截错误,但是不会中断程序
console.log(errr.message);
throw new Error('选择器报错!!!')
return//return 耳朵作用是用来中断程序
}
finally{//一定会执行的代码
alert('这个不管如何,一定会执行的代码')
}
}
</script>

72369899793

(3).debugger

72369941592

用来断点,调试

11.处理this

(1).this指向

1.普通函数

72369992926

谁调用,this就指向谁

2.箭头函数

72370015949

注意:箭头函数不建议在原型函数中写,因为由于构造函数,原型函数的this指向的是实例化的对象,,使用箭头函数将会影响到其this所指向的实例化对象,时期不会指向其实例化对象

72370044834

2.改变this

72370075876

1.call()

72370121523

1
2
3
4
5
6
7
8
9
10
11
12
13
<script>
let app={
name:'lalalalal'
}
function gender(x=0,y=0)
{
return x+y
}
let s1= gender.call(app,23,342)//将this指针指向app对象,后面的数字是正常的传递参数
let s2=gender.call(app)//也可以直接这样写//.call()调用函数
console.log(s1);
console.log(s2);
</script>
2.apply()

72370151960

1
2
3
4
5
6
7
8
9
10
11
12
13
<script>
function app(...arr)
{
console.log(arr.reduce((a,b)=>a+b));
}
app.apply(Object,[12,23,12,31,2,31,43,123])//注意的是,在这里面的第二个参数必须是数组,这是与call()的不同之处
//也可以这样写
let array=[12,143,24,3,124,1,231,24,1]
let p1=Math.max.apply(Math,array)
let p2=Math.min.apply(Math,array)
console.log(p1);
console.log(p2);//apply()的用法
</script>

//求最大值和最小值的另一种方法

3.bind()

这个不会立马调用函数,前面两个会调用函数

72370298679

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<script>
function app()
{
console.log(this);
}
let arr={
name:'s'
}
app.bind(arr)//不会调用函数
//会有一个返回值,返回的是这个函数的拷贝赋值的函数
let s1=app.bind(arr)
s1()
app()
</script>

72370340738

//定时器的另一种写法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<script>
document.querySelector('button').addEventListener('click',function(){
this.disabled=true
setTimeout(function(){
this.disabled=false
}.bind( document.querySelector('button')),2000)
})
//或者可以这样写
document.querySelector('button').addEventListener('click',function(){
this.disabled=true
setTimeout(function(){
this.disabled=false
}.bind(this),2000)
})
</script>

72370438904

12.性能优化

(1).防抖

72370517029

72370519164

利用lodash的js库来实现防抖,网上有,这里就不例举了

//手写代码://主要的思路就是定时器,通过实践监听的鼠标移动的方法来实现,如果继续移动的话就删除定时器,反之就继续实现功能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
<!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
{
position: relative;
width: 400px;
height: 400px;
background-color: aqua;
margin: 300px auto;
}
.box2
{
top: 150px;
left: 150px;
position: absolute;
width: 100px;
height: 100px;
background-color: azure;
font-size: 60px;
line-height: 100px;
text-align: center;
color: black;
}
</style>
</head>
<body>
<div class="box1">
<div class="box2">0</div>
</div>
<script>
let i=0
function move()
{
++i
document.querySelector('.box2').innerHTML=`${i}`
}
function prevent(funct,time)
{
let timer
return function(){
if(timer)clearTimeout(timer)
timer=setTimeout(function(){
funct()
},time)
}
}
document.querySelector('.box1').addEventListener('mousemove',prevent(move,100))
</script>
</body>
</html>

(2).节流

72371211100

72371233920

1.lodash提供的节流方式,这里不再写明,自己去网络上找

2.手写啊啊啊啊啊啊啊啊啊啊啊啊啊啊

//需要注意的是,在定时器内部是不能对定时器清除的,因为定时器还在运作,所以要使用的是定时器赋值为null

//核心思路与防抖的一样

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
<!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
{
position: relative;
width: 400px;
height: 400px;
background-color: aqua;
margin: 300px auto;
}
.box2
{
top: 150px;
left: 150px;
position: absolute;
width: 100px;
height: 100px;
background-color: azure;
font-size: 60px;
line-height: 100px;
text-align: center;
color: black;
}
</style>
</head>
<body>
<div class="box1">
<div class="box2">0</div>
</div>
<script>
let i=0
function move()
{
++i
document.querySelector('.box2').innerHTML=`${i}`
}
function prevent(funct,time)
{
let timer
return function(){
if(!timer)
{
timer=setTimeout(function(){
funct()
timer=null
},3000)
}
}
}
document.querySelector('.box1').addEventListener('mousemove',prevent(move,100))
</script>
</body>
</html>

(3).总结

72371407605