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).单行注释 符号:// . 快捷键:ctrl+/ (2).块注释 符号:/* */
快捷键:shift+alt+a
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.变量 1 2 3 4 5 6 7 8 9 10 11 <script> let name 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>
let和var的区别
在较旧的javascript中,使用关键字var来声明变量,而不是let
现在的开发中一般不是用var,只是我们可以在更老的程序中看到它
let是为了解决var的一些问题
var声明:
可以先使用,再声明(不合理) var声明过的变量可以重复声明 比如变量提升,全局变量,没有块级作用域等等 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) 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 ))document .write (app.indexOf (4 ,5 )) </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的用法:
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 ) { return app+'I do not know!!!' } ) console .log (srr); </script > </body > </html >
2.数组中join方法得用法:
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 >
3.遍历数组的方法forEach 语法与map的相类似
但是这个方法他不会返回一个数组
1 2 3 4 5 6 7 <script> let arr=['blue' ,'red' ,'gree' ] arr.forEach (function (a,b ){ console .log (a); console .log (b); }) </script>
4.筛选数组方法
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 ] let arr1=arr.filter (function (app,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 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 注意:
常量不可以重新赋值,声明的时候必须初始化 不需要重新赋值的数据可以使用const来命名 6.数据类型 javascript是弱数据类型语言
数据类型:
基本数据类型 引用数据类型 (1).基本数据类型 number数字型
string字符串型
1.通过单引号(‘’),双引号(“”)或者反引号(`)包裹的数据都叫字符串
单引号与双引号在本质上没有任何的区别
无论是单引号还是双引号必须成对出现 单引号和双引号可以相互嵌套,但是不可以自己嵌套自己(外双内单,或者外单内双) 非必要的时候可以使用转义符\,输出单引号或者双引号 2.字符串拼接:+运算符可以实现字符串的拼接
3.字符串模板:
语法:``(反引号)
内容拼接时,用${变量名字}
boolean布尔型
有两个数据值true和false
undefined未定义型
没有赋值的变量,就是未定义数据类型
null空类型
一个值:null
空类型
typeof运算符可以检测数据的类型
有两种写法:
1.作为运算符:typeof 变量名字
2.函数形式:typeof(变量名字)
有括号和没有括号是一样的
(2).引用数据类型 (3)算术运算符 + - * / % (4).NaN NaN代表一个计算错误,它是一个不正确或者未定义的数字操作所得的结果 NaN是粘性的,任何对NaN的操作都会返回NaN 1 2 3 4 5 <script> document .write ("字符型数据" -19 ) document .write (NaN +19 ) document .write (NaN ==NaN ) </script>
7.数据类型转换 使用表单,prompt()获取过来的数据默认是字符串类型的,因此不能直接进行加法运算
(1).隐式转换 +号两边只要有一个是字符串,都会把另一个转换为字符串 除了+号以外的算术运算符,比如-*/等都会把数据转换为数字类型 +号作为正号解析可以转换为数字型
任何数据和字符串相加结果都是字符串
(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).运算符优先级 小括号 () 一元运算符 ++ – ! 算术运算符 先*/%后+- 关系运算符 > >= < <= 相等运算符 == != === !== 逻辑运算符 先&&后|| 赋值运算符 = 逗号运算符 , (6).展开运算符
1 2 3 4 5 6 7 8 9 10 11 <script> let arr1=[12 ,23 ,34 ,23 ,121 ,33 ] console .log (...arr1); let app=[12 ,23 ,24231 ,4 ,2 ] console .log (Math .max (...app)); let arr2=[12 ,23 ,34 ,45 ,5 ,66 ,7 ] let arr=[...arr1,...arr2] console .log (arr); </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>
函数表达式和具名函数的不同之处:
具名函数的调用可以写到任何位置 函数表达式,必须先声明函数表达式,后调用 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).逻辑运算符中的短路 短路:只存在于&&和||中,当满足一定条件会让右边代码不执行
&&:左边为false就短路 ||:左边为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) document .write (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) document .write (app[kkk]) }
还有数组对象:
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类
getTime():返回实例距离1970年1月1日00:00:00的毫秒数 getDate():返回实例对象对应每个月的几号(从1开始) getDay():返回星期几,星期日为0,星期一为1,以此类推 getYear():返回距离1900的年数 getFullYear():返回四位的年份 getMonth():返回月份 (0表示1月,11表示12月) getHours():返回小时(0-23) getMilliseconds():返回毫秒 (0-999) getMinutes():返回分钟(0-59) 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 ()) 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 ())/s1console .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对象
欲修改标签里面的内容:
对象.innerText属性 对象.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.样式属性=值
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去代替
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(‘类名’)
//查找类
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' ) 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 ) name.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 ="" > <button > 按钮</button > <script > const app=document .querySelector ('input' ) console .log (app.checked ); app.checked =true app.checked ='true' const spp=document .querySelector ('button' ) console .log (spp.disabled ); spp.disabled =true </script > </body > </html >
标准属性
:
标签自带的属性,比如:class,id,title等,可以直接使用点语法操作比如:disabled,checked,selected
自定义属性
:
在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 ); console .log (aaa.dataset .ssmm ); </script > </body > </html >
(6).定时器-间歇函数 1.介绍
功能:如网页中每隔一段时间需要执行一段代码,不需要认为手动去操 作,使用定时器能重复执行代码
定时器函数可以开启和关闭定时器
如:网页中的倒计时
定时函数有两种
2.定时器的语法及使用
开启定时器:
作用:每隔一段时间调用这个函数
间隔时间单位为毫秒
关闭定时器:
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 (function ( ) { document .write (123 ) }, 1000 ) function app ( ) { document .write ('每过一秒就打印一次' ) } setInterval (app, 1000 ) let number = setInterval (app, 1000 ) document .write (number) clearInterval (number) </script > </body > </html >
(7).事件监听 语法:
元素对象.addEventListener(‘事件类型’,要执行的函数)
三要素:
事件源:那个dom元素被触发了,要获取dom元素 事件类型:用什么方式触发,比如鼠标单击click,鼠标经过mouseover等 事件调用的函数:要做什么事 注意:事件类型要加引号
函数是点击之后再去执行,每次点击都会执行一次
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' ) const spp=document .querySelector ('.box2' ) 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 ; } .strant { width : 500px ; height : 60px ; 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
(11).回调函数 如果将·函数A作为参数传递给函数B时,我们称函数A为回调函数
(12).事件流
事件流的两个阶段:事件捕获,事件冒泡;
事件流指的是指的是事件完整过程中的流动路线
1.事件捕获
从大的往下查找,从大到小
2.事件冒泡
从小的到大的查找,从小到大(注意的是,事件的类型必须要相同)
3.阻止冒泡
4.事件解绑
(13).事件委托
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 ){ if (e.target .tagName ==='LI' ) { e.target .style .color ='red' } }) </script > </body > </html >
(14).阻止冒泡
(15).页面加载事件
(16).元素滚动事件
可以写页面的打开所在的位置;可以写其位置
(17).页面尺寸事件
(17).元素尺寸于位置-尺寸
(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>
2.方法
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 () app.innerHTML =date.toLocaleString () app.innerHTML =date.toLocaleTimeString () </script > </body > </html >
3.时间戳:
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; 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节点
2.查找节点
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 ) </script > </body > </html >
3.增加节点
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 ); 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) let li1=document .createElement ('li' ) li1.innerHTML ='我是第二个小li' app.insertBefore (li1,ul.children [0 ]) </script > </body > </html >
4.删除节点
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端事件
(21).插件
4.BOM (1).简介
(2).定时器–延时函数
//注意:不能再定时器的内部对定时器进行删除,因为定时器还在运行,不能删除定时器,就是对定时器进行clear的操作,但是可以对定时器赋值为null的操作
1 2 3 4 <script> let timee=setTimeout (function ( ){alert ('时间到了!!!' )},2000 ) </script>
(3).js执行机制
(4).Window对象 1.location对象
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 >
2.navigator对象
3.histroy对象
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介绍
2.分类(两种)
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 > localStorage .setItem ('name' , '第一次存储信息' ) console .log (localStorage .getItem ('name' )) localStorage .setItem ('age' , 19 ) console .log (localStorage .getItem ('age' )) </script > </body > </html >
这个的存储方式的写法和上面的写法完全一样!!!
//注意的是,在存储的写法中,键(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字符串存储
//这个才是正确的存储方式
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)) console .log (localStorage .getItem ('obj' )); </script > </body > </html >
当把要拿来用是,要把JSON字符串转换为对象,这个时候就用到JSON.parse()这个方法
5.正则表达式 (1).简介
(2). 语法
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) </script > </body > </html >
注意的是这个返回的是一个数组
(3).元字符
1.边界符
1 2 3 4 5 <script> console .log (/汗/ .test ('我出汗了!!!' )) console .log (/^汗/ .test ('我出汗了!!!' )) console .log (/汗$/ .test ('出了好多汗' )) </script>
2.量词
//逗号左右两侧千万不能出现空格
1 2 3 4 5 6 7 8 <script> console .log (/^含*$/ .test ('含含含' )) console .log (/^含+$/ .test ('含含含含' )) console .log (/^含+$/ .test ('' )) console .log (/^含?$/ .test ('含含含' )) console .log (/^含?$/ .test ('' )) console .log (/^含?$/ .test ('含' )) </script>
3.字符类
在括号里的只能出现一次,只能选一次
(4).修饰符
1 2 3 4 <script> console .log (/java/ .test ('java' )); console .log (/java/i .test ('JAVA' )); </script>
1 2 3 4 5 6 7 <script> let app='前端是一门编程语言,学完之后会有很高的工资!!!' let spp=app.replace (/前端/ ,'java' ) console .log (spp); </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).获取元素
document对象 - 基础起点,所有DOM操作的根对象。
getElementsByTagName() - 方法用于获取文档中所有具有指定标签名的元素集合(HTMLCollection)。
//获取标签名,在括号里要加入标签名
getElementsByClassName() - 方法用于获取文档中所有具有指定类名的元素集合(HTMLCollection)。
//class类名……
getElementsByName() - (注意:图片文字中未直接显示,但根据图片信息推测存在)方法用于获取文档中所有具有指定name
属性的元素集合(NodeList)。
//name名……
getElementById() - (注意:图片文字中拼写错误为getElementByld
)方法用于获取文档中唯一具有指定ID的元素。
//id名……
querySelector() - 方法返回文档中匹配指定CSS选择器的第一个元素。
//只会返回第一个元素的,可以是.类名;#id名
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' ) let content=document .createTextNode ('我是文本内容' ) app.appendChild (content) 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获取元素位置
css操作
DOM事件:
1.HTML事件处理:
2.DOM0事件:
3.DOM2事件:
事件类型之鼠标事件:
Event事件对象:
事件对像方法:
事件类型之键盘事件:
事件类型之表单事件:
事件代理:
定时器:
这个定时器只会发生一次,不会发生第二次
对于复选框:
四.javascript进阶 1.作用域 (1).局部作用域 1.函数作用域
在函数内部申明的变量只能在函数内部进行访问,在函数外部无法进行直接访问
2.块作用域
在javascript中使用{}包裹的代码称为代码块,代码内部申明的变量外部无法被访问(也由可能被访问到)
var申明的不会产生块作用域
(2).全局作用域 在script标签和.js文件就是所谓的全局作用域,在全局作用域中申明的变量在函数内部也可以被访问到
(3).作用域链
2.垃圾回收机制
(1).引用计数法
(2).标记清除法
3.闭包
闭包可以实现在函数外部可以使用函数内部的变量
闭包可以实现一个数据的私有,不能被外界所修改,保证了数据的安全
闭包可能会导致内存泄露
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>
(2).函数参数 1.动态参数 arguments是函数内部内置的伪数组变量,它包含了调用函数时传入的所用实参
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>
2.剩余参数
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 ) { 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 ) { 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.基本语法
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 ) let fun5 =x=>x+x+x*4 console .log (fun5 (23 )); let fun6 =(name )=>({username :name}) fun6 ('老刘' ) console .log (fun6 ('老刘' )); </script>
箭头函数里没有arguments动态参数
2.箭头函数this
1 2 3 4 5 6 7 8 9 10 11 <script> let app= { name :'老刘' , getname :()=> { console .log (this ); } } app.getname () </script>
5.解构赋值 (1).数组解构
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>
//一定要加分号;
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>
//也可以按需导入赋值
(2).对象解构 1.对象
1 2 3 4 5 6 7 8 9 10 11 12 <script> let obj= { name :'老刘' , age :18 } let {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.数组对象
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 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} ) { 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 (4 n) { 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 > <script > 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.深入对象
1 2 3 4 5 6 7 8 9 <script> let obj= { name :1233 } let obj1=new Object ({name :3123 }) </script>
(1).构造函数
//注意:构造函数的首字母规定要大写
(2). 实例成员&静态成员
实例成员包括实例属性和实例方法
就是实例化了的对象中的属性和方法
静态成员指的是未实例化的对象得属性和方法
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.内置构造函数
(1).Object方法 1.Object.values与Object.keys
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()方法
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);console .log (returnedTarget === target);
(2).Array方法
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 ) 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 ) console .log (ans); </script>
2.其他方法
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); </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方法
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> let arr='pink,lalala,nonono' let arr1=arr.split (',' ) console .log (arr1); let str='今年不用做核算精测了' console .log (str.substring (5 )); console .log (str.substring (5 ,7 )); let app='检查是否开头的是不是真的!!!' console .log (app.startsWith ('检查' )); console .log (app.startsWith ('是否' )); console .log (app.startsWith ('开头' ,4 )); let arr2='看看这里面是否含有某个字符或者字符串' console .log (arr2.includes ('里面' )); console .log (arr2.includes ('看看' , 3 )); </script>
(4).Number方法 1.toFixed()
8.深入面向对象
javascript是通过构造函数来实现面向对象的封装
javascript通过构造函数的面向对象会产生内存浪费的问题
(1).原型
构造函数和原型对象中的this都指向实例化的对象
1 2 3 4 5 6 7 8 9 10 11 <script> let arr=[1 ,313 ,1 ,1 ,31 ,2 ,1 ] Array .prototype .max =function ( ) { return Math .max (...this ) } console .log (arr.max ()); </script>
(2).constructor属性
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 = { sing :function ( ){ console .log ('man' ); } } Star .prototype = { constructor :Star , sing :function ( ){ console .log ('man' ); } } </script>
(3).对象原型
对象原型__proto__指向构造函数的原型对象
1 2 3 4 5 6 <script> function App ( ){} let cpp=new App () console .log (cpp.__proto__ ===App .prototype ); </script>
(4).原型继承 //这种写法是错误的写法,不是真正的语法写法,这里只是示例
//这种继承会有缺点,就是两个或者多个对象对共享的对象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).原型链
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; o instanceof D; o instanceof Object ; C.prototype instanceof Object ; C.prototype = {}; var o2 = new C ();o2 instanceof C; o instanceof C; D.prototype = new C (); var o3 = new D ();o3 instanceof D; o3 instanceof C;
9.深浅拷贝 (1).浅拷贝 拷贝的是地址
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>
(2).深拷贝 深拷贝有3钟方式:
1.通过递归实现深拷贝
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))再将其转化为原来的对象,赋值给新的一个对象
10.异常处理 (1).throw抛日常
1 2 3 <script> throw "用户没有传递参数进来" </script>
1 2 3 <script> throw new Error ('警告,错误!!!' ) </script>
(2).try/catch捕获错误信息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <script> function fun ( ) { try { let app=document .querySelector ('div' ) app.innerHTML ='lalalalal' }catch (errr){ console .log (errr.message ); throw new Error ('选择器报错!!!' ) return } finally { alert ('这个不管如何,一定会执行的代码' ) } } </script>
(3).debugger
用来断点,调试
11.处理this (1).this指向 1.普通函数
谁调用,this就指向谁
2.箭头函数
注意:箭头函数不建议在原型函数中写,因为由于构造函数,原型函数的this指向的是实例化的对象,,使用箭头函数将会影响到其this所指向的实例化对象,时期不会指向其实例化对象
2.改变this
1.call()
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 ) let s2=gender.call (app) console .log (s1); console .log (s2); </script>
2.apply()
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 ]) 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); </script>
//求最大值和最小值的另一种方法
3.bind() 这个不会立马调用函数,前面两个会调用函数
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>
//定时器的另一种写法
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>
12.性能优化 (1).防抖
利用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).节流
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).总结