JavaScript
2021-06-02 15:14:44 47 举报
AI智能生成
详细的JavaScript基础到高级部分的整理。其中都是前端开发人员对JavaScript的必学部分。笔记对应的课程视频。https://www.bilibili.com/video/BV19Q4y167As/
作者其他创作
大纲/内容
ECMAScript
概述
JavaScript 最初被创建的目的是“使网页更生动”。<br><br>这种编程语言写出来的程序被称为 脚本。它们可以被直接写在网页的 HTML 中,在页面加载的时候自动执行。<br><br>脚本被以纯文本的形式提供和执行。它们不需要特殊的准备或编译即可运行。
编程语言分类<br>
编译型
经过编译,产生编译之后文件,才可以运行。比如Java<br>
运行效率要快一些
解释型<br>
不需要编译javascript
发展史:
- 1992年,第一门脚本语言:ScriptEase,专门用于表单校验<br>- 1995年,Netscape(网景)公司开发了一门脚本语言:LiveScript,后面更名为JavaScript<br>- 1996年,微软抄袭JavaScript,开发出JScript<br>- .1997年,ECMA组织,指定了脚本语言规范:ECMAScript<br>
版本号与发布时间
ES1:1997 年 6 月 —— ES2:1998 年 6 月 —— ES3:1999 年 12月 —— ES4:未通过
ES5:2009 年 12月
ES6 / ES2015:2015 年 6 月
ES7 / ES2016:2016 年 6 月
ES8 / ES2017:2017 年 6 月
ECMAScript
- 可以来解释JavaScript的一个标准,<br>- 最新版本到es8,引入一行明确的设定及面向对象编程<br>- 但是大部分浏览器还只停留在es5代码上<br>- 开发环境---线上环境 版本不一致<br>
面向对象编程
类的设计与对象的使用
浏览器JavaScript组成:
由ECMAScript、BOM、DOM组成
Bom指的浏览器内置对象
Dom就是html文档对象
JavaScript与ECMAScript有点类与对象之间关系
开发工具
WebStorm:最强大,可以查看语法提示文档。推荐使用
NotePad++、Sublime Text、VSCode、Hbuilder
浏览器的开发者工具
调出方式,一般快捷键是F12或Ctrl + Shift + i<br>
了解如何查看元素和查看控制台信息<br>
ECMAScript页面结合
概念:JavaScript是一门脚本,要起作用,必须结合页面使用
标签名称
script
分类
内部结合<br>
直接在页面文件中编写script标签,将js代码编写到script标签内容中
type="text/javascript",指定写的是 Javascript 脚本<br>
练习
创建一个页面,然后显示一个消息 “I’m JavaScript!”。
外部结合
在页面文件中使用script标签的src属性引入外部的js文件
src
需要引入的js文件路径<br>
绝对路径
引入第三方服务器上的JS文件<br><script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"><br>也可以引入本地服务器上的JS文件<br>
相对路径
引入本地服务器JS文件
练习<br>
创建一个页面,然后显示一个消息 “I’m JavaScript!”。
行内写法<br>
写在 html 标签的事件属性中<br>
onclick="javascript:alert(1)"
javascript:void(0) <br>
这个代码其实什么都没有做,了解一下即可
ECMAScript输出
控制台交互
console.log(常量或变量列表)
将内容输出到开发者工具中的Console窗口,多个使用逗号分隔
console.log(1, "Hello")<br>
输出两个常量
console.dir(对象列表)
输出一个对象结构,目前先记住,后面讲解
基本交互框
alert():弹出框<br>
prompt(标题, 默认值)
confirm():确认框
输出到页面<br>
document.write()
document.writeln()
练习:弹出一个prompt()。输入自己的名字,并且使用log和alert以及write分别输出到相应位置上<br>
ECMAScript标识符
概念:一切可以自定义的名称就是标识符。比如变量名、函数名<br>
命名规则
首字母必须是字母、下划线(_)或美元符号($),不能是数字
除首字母外,其他字符可以是字母、数字、下划线或美元符号($)
普通标识符(用作变量名、函数名和循环语句中用于跳转的标记)不能是保留字符
在严格模式下,arguments和eval不能用作变量名,函数名或者参数名
命名规范
即驼峰命名规范<br>
变量名和函数名:首字母小写,后续单词首字母大小。xxxYyyZzz
常量名:全部大写,多个单词下划线(_)分隔。XXX_YYY_ZZZ
类名:所有首字母都是大写。XxxYyyZzz<br>
见名知意
ECMAScript关键字与保留字
关键字
ES6
保留字
始终保留<br>
enum(枚举)
严格模式中保留
模块代码中保留
await
ECMAScript变量
概念:保存数据,可以修改,可以重复使用,会占用内存。
关键字<br>
var
声明提升:即支持先使用后定义,定义语句会被放到作用域内的第一行<br>
没有块级作用域
定义在全局作用域的变量,会变成window对象的属性
变量可以重复定义
let
ES6新增,推荐使用。<br>
const
ES6新增,定义常量使用
定义
变量
let 变量名;<br>
var 变量名;<br>
全局变量:变量名 = 初始值;<br>
写在script标签中的的叫做全局变量,或者在JS文件中的函数之外定义的<br>
常量
const 变量名 = 初始值;<br>
不管是变量还是常量,都支持同时定义多个变量<br>
初始化<br>
变量名 = 初始值;<br>
作用域
全局作用域
变量定义在script标签之间,但在函数之外。
在整个HTML标签中有效<br>
块级作用域
{}之间
函数作用域
var定义变量依然会被提升作用域,但只在函数的范围内<br>
可以使用全局作用域的变量,但函数作用域中的变量无法被全局作用域的代码使用
函数作用域中,默认有一个arguments对象,保存所有函数的实参,是一个类似于数组的对象
注意:在JavaScript中,可以不使用分号";"来表示语句结束,但从严格意义上来说,每个语句加上;对性能或压缩更好
Java是强类型语言,JavaScript是弱类型语言
- 强类型语言:<br> - 在定义变量时,要确定数据类型,在赋值时,只能赋值指定类型的数据<br>- 弱类型语言:<br> - 在定义变量时,不确定数据类型,在赋值时,赋值多种类型的数据<br>
练习:定义三个变量分别保存个人的名字,年龄,学校。然后打印在控制台<br>演示一下变量未定义的错误,和变量未赋值的情况<br>
ECMAScript注释
概念:用来注释js脚本代码,给开发人员看的,浏览器不会解析执行
分类:
单行 //
多行 /* */
文档注释/** */<br>
ECMAScript数据类型
分类:
原始数据类型:
Undefined
只有undefined一个值,表示变量未被初始化。<br>
Null
表示变量被没有分配堆内存空间,一般是针对引用类型
undefined 值是由 null 值派生而来的,当null == undefined的结果为true<br>
Number<br>
整数
let a = 10;<br>
let a = 10.;<br>
浮点数(小数)
let f = 0.1;<br>
let f = .1;<br>
科学计数法:数值e幂数。<br>如2.134e7:就是21340000<br>
范围属性<br>
最大值:Number.MAX_VALUE
最小值:Number.MIN_VALUE
正无穷大:Number.POSITIVE_INFINITY
5/0
负无穷大:Number.NEGATIVE_INFINITY
5/-0
NaN(not a number)
0/0
任何涉及 NaN 的操作始终返回 NaN(如 NaN/10)
NaN只能通过isNan()方法来判断<br>
NaN 不等于包括 NaN 在内的任何值
示例<br>
转换为Numer<br>
Number()
parseInt(x, y)
将x的转换为10进制的结果,通过y告诉我们x是什么进制<br>
x:浮点型或字符串<br>
y:进制
parseFloat(x, y)
String<br>
写法
ES5,字符串("abc"、'abc')
ES6,`abc`
通过${变量名}使用
不可变性<br>
ECMAScript 中的字符串是不可变的(immutable),意思是一旦创建,它们的值就不能变了。要修改<br>某个变量中的字符串值,必须先销毁原始的字符串,然后将包含新值的另一个字符串保存到该变量
let lang = "Hello" + "JavaScript";<br>
字符串拼接
+:从左到右执行,只要遇到字符串,后续的都是字符串拼接
concat(字符串, ...)
长度<br>
length
转换为String
toString()
null和undefined没有此方法<br>
数字类型,可以传入进制参数<br>
"" + 值<br>
String():构造方法<br>
模板字符串
使用``反引号包裹
可以分多行写
可以使用变量
${变量名}<br>
Boolean<br>
false:假值
undefined
0
null
""
true:真值<br>
Symbol
符号类型,用于表示一个独一无二的值
一般用于解决对象的私有属性或方法<br>
不支持new Symbol()<br>
引用数据类型:
Object
Date:日期类
RegExp:正则表达式
Function:函数
原始值包装类型<br>
String
Boolean
Number
单例内置对象
Global
window
Math
数学类<br>
集合引用类型
Array
Map
Set
查看值类型<br>
如图7种类型
typeof
typeof 值或变量<br>
typeof()
typeof(值或变量)
基础作业一
ECMAScript运算符
一元运算符:
正数+<br>
负数-
逗号操作符<br>
算术运算符:
+
-
*
/
%,取余或取模
++在前
++在后
--在前
--在后
注意:除了+,其它的都自动将字符串格式数字转换为number<br>
赋值运算符:
=
可以在定义变量时使用<br>
扩展
+=
-=
*=
/=<br>
%=
不可以在定义变量时使用
比较运算符:
>
<
>=
<=
==
!=<br>
===<br>
!==
返回的结果都boolean类型<br>
逻辑运算符:
&:逻辑与,所有表达式都会运行完
|:逻辑或
&&:短路与,只要有false,后面的表达式是不需要运行的,则结果为false<br>
||:短路或,只要有true,后面的表达式是不需要运行的,则结果为true
^:异或,不一样则为true
位运算符<br>
&:与运算,同为1,则为1
|:或运算,有1则为1
^:异或运算,不一样则为1
<<:左移
>>:右移
>>>:无符号右移<br>
针对二进制运算,同位比较<br>
三元运算符:
条件表达式 ? 表达式1 : 表达式2<br>
等同于if-else语句
运算符的优先级<br>
ECMAScript选择与循环结构
选择结构
if语句
if
if-else
if-else if<br>
if-else if-else<br>
可以嵌套,不推荐过多嵌套,最多3层<br>一般做区间选择比较多。<br>演示原始数据在if条件中使用<br>
switch语句
switch
case<br>
精确匹配
整型<br>
字符串
范围匹配<br>
比较运算符
break
default
作业
循环结构
作用:循环主要用于做一类重复的事情。比如从1打印到10.或者将某个变量重复打印多少
主要部分<br>
初始化部分<br>
条件部分<br>
迭代部分<br>
循环体部分
注意:以上1~3这三个部分可以写多个语句,使用“,”分隔
for循环
计数for循环<br>
for-in循环
for-of循环(ES6)
while循环<br>
do-while循环
循环嵌套<br>
外循环和内循环<br>
总次数是由外循环的次数与内循环次数相乘
特殊字符
\n:换行
\t:相当于tab键
流程控制语句
break
结束整个循环,如果有嵌套循环,就近原则<br>
continue
结束当次循环,循环没有结束,继续下一次,如果有嵌套循环,就近原则
return
结束函数
with语句(了解)
不推荐使用<br>
ECMAScript函数基础
写法<br>
函数声明(也叫全局函数):function 函数名(形参列表) {函数体}<br>
全局函数在整个全局作用域都有效。因为会有声明提升。<br>所以函数的调用代码在定义代码之前也不会有问题<br>
函数表达式:let 函数名 = function(形参列表) {函数体};<br>注意分号结尾,否则可能会影响后续的代码<br>
函数表达式,其实就是将一个函数赋值给一个变量。<br>该变量就是函数名,所以在使用之前一定要先定义。<br>
注意:在JavaScript中函数的形参与实参不需要有对应关系,这与Java等其它语言不同。<br>因为这一点,所以JavaScript中的函数没有重载<br>
调用
有参数时调用:函数名(实参列表)<br>
没有参数时调用:函数名()
函数参数<br>
形参与实参不需要一一对应,在 JavaScript 中无法明确形参类型,只能在调用时传值决定<br>
ES6允许在形参定义时,设置默认值
arguments对象
每个函数都自己arguments对象,是一个类似数组的结构,里面包含了函数的实参列表
可变量参数
...参数名:本质上该参数就是一个数组,可以接收不限长度的实参
必须在参数列表的最后
返回值<br>
在JavaScript中,函数有没有返回值是不固定的
需要返回值直接在函数体中合适的地方加上return 变量或数据;即可<br>
练习<br>
使用不同的函数写法实现
定义一个函数,实现两个数字相加
定义一个函数,实现两个数字的最大值或最小值,并返回
定义一个函数,实现求所有实参的最大值或最小值,并返回,提示需要使用到循环
定义一个函数,实现对身份证号码的校验<br>
身份证号码的校验码<br><br>校验码生成规则:<br>先将第1—17位的数字,分别乘以对应的系数7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2,然后将累加和除以11求余数,所得余数与校验码的对应规则如下:<br>余 数:0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10<br>校验码:1,0,X,9, 8, 7, 6, 5, 4, 3, 2<br>输出:<br>每个测试用例输出一行。若校验码正确,则输出"yes",否则输出"no"。<br>测试案例:<br>id_hao = [‘450202198703173404’, ‘450202198703173405’, ‘522424197906101261’, ‘52032819821124009X’]
函数的分类
普通函数<br>
匿名函数:(function(形参列表) {函数体})<br>
立即执行函数:(function(形参列表) {函数体})();<br>
嵌套函数:函数体中又定义了一个函数<br>
嵌套函数只能在其定义的函数中直接使用,也可以将嵌套函数做为函数的返回值
闭包(closure)<br>
① 函数嵌套函数<br>② 函数内部可以引用函数外部的参数和变量<br>③ 参数和变量不会被垃圾回收机制回收<br><br>闭包是一种现象,通过debug可以看到
回调函数:将一个函数做为参数传递到另一个函数中
比如setTimeout、setInterval()<br><br>配合异步函数使用,如果需要得到异步函数中的结果,可以使用回调函数<br><br>实现了将函数的定义与调用由不用的开发人员执行
箭头函数:ES6提供的一个新的写法<br>
概念
全局函数写法
无参:let 函数名 = () => {函数体}<br>
一个参数:let 函数名 = 参数名 => {函数体}<br>
多个参数:let 函数名 = (参数列表) => {函数体}<br>
注意:函数体中如果只有一行代码,可以省略{}。如果需要返回值也可以省略return关键字<br>
箭头函数的this指向与其它函数不一样。后面讨论<br>
箭头函数不能用过构造函数<br>
字符串函数<br>
var 函数名 = new Function("形参列表","函数体");
框架设计时会用到,其它时候使用比较少。了解即可<br>
构造函数
创建某一类对象,首字母大写
通过 this 定义或调用属性和方法
必须和new一起使用才有意义。这也是构造函数和普通函数最本质的区别<br>
ECMAScript引用数据类型
Object
创建方式<br>
let obj = {};<br>
let obj = new Object();<br>
obj 就是对象名,也可以称为变量名。<br>
属性<br>
添加属性<br>
创建对象时添加
let obj = {属性名: 属性值, 属性名: 属性值,}<br>
多个属性的定义要使用逗号分隔,最一个属性的逗号可以不写<br>
创建对象后添加<br>
"."语法
对象名.属性名
[属性名]语法<br>
属性名支持使用变量
对象名[属性名]
使用对象属性<br>
通过对象名.属性名或对象名[属性名]
属性的赋值,及获取属性的值都是在使用属性
默认没有length属性<br>
方法
方法的本质就是函数。实参列表一般与定义函数时的形参列表一一对应,不对应该也没关系。实参列表都会在函数的arguments对象中一一映射
添加方法
创建对象时添加
let obj = {方法名: function(形参列表) {方法体}}<br>
多个属性的定义要使用逗号分隔,最一个属性的逗号可以不写<br>
创建对象后添加<br>
"."语法
对象名.属性名 = function(形参列表) {方法体}<br>
[属性名]语法<br>
属性名支持使用变量
对象名[方法名]= function(形参列表) {方法体}
使用:通过对象名.方法名(实参列表)<br>
一个对象中的方法使用自己的属性和方法时,要通过this.属性名或this.方法名<br>
delete<br>
删除属性和方法
作业
定义一个对象,有name、age、address三个属性和一个info()函数,<br>info函数返回"姓名:XXX,年龄:XXX,address:XXX"。<br>
对象的遍历
因为Object中默认没有length属性,所以不能使用计数for循环
for key in obj<br>
迭代器方法<br>
entries()
keys()
values()
对象遍历默认不能使用for-of循环<br>
自定义迭代器要求<br>
有一个名称为[Symbol.iterator]的函数<br>
该函数的返回值为一个对象
返回的对象中有一个next函数
next函数返回一个包含value和done属性的对象
最后一条记录,done的值为true。
生成函数和yield
ES6
属性名简写:当属性key和value的变量名一致时,可以简写
[]语法
方法名简写:方法名: function(){}<br>
对象解构<br>
支持嵌套
形参中的对象也支持解构
Symbol在Object中的使用主要体现在私有属性的创建
因为在ES5之前,Object中的属性和方法名都是使用字符串<br>这样定义的属性和方法可以随意被开发人员修改<br>
但是使用Symbol定义的属性和方法就不会
练习:将图片中的数据,一行定义一个对象保存<br>
集合引用类型
Array
特点<br>
JavaScript的数组类型
长度不是固定的
索引的只要>=0,即可,否不会修改length属性
每个元素都可以是任意类型的值
创建方式
构造函数<br>
let 数组名 = new Array();<br>
let 数组名 = new Array(长度);<br>
let 数组名 = new Array(元素1, 元素2, ...);<br>
简写
let 数组名 = [元素1, 元素2, ...]<br>
ES6
Array
of(值1, 值2, ...)
from(类数组结构, function() {})
长度<br>
数组名.length
元素<br>
数组元素指的是每个位置上的数据
可以通过数组名[索引]操作赋值或读取的操作
索引
数组正常的索引必须>=0,不然不会引起长度属性的变化<br>
字符串也可以作为索引效果与负数一致<br>
函数的可变参数:本质上是一个数组<br>
...变量名<br>
扩展(展开)操作符,ES6。
符号:...
...数组名
合并多个数组,[...数组名1, ...数组名2, 等]
方便的实现数组的复制
...形参名
表示可变参数,本质是将参数列表保存到一个数组中<br>
...对象名<br>
不支持,会报错
但支持{...对象名},实现一个对象的浅复制
全并多个对象,{ ...对象1, ...对象2, 等}<br>
参考文档:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Spread_syntax
遍历
使用循环
计数循环是无法遍历字符串和负数索引上的元素,不过可以通过for-in循环
for-of
支持解构写法,针对二维数组<br>
迭代方法,[Symbol.iterator]
forEach方法
练习
练习:只能定义一个数组,只能使用一个循环,实现图中按钮的排列以及功能
练习:产生10个在1~100之间的随机整数,并保存到数组中。
练习:实现一个随机班级人员抽查程序:<br>(1)记录每个学员被抽到的次数<br>(2)每一轮必须保证所有学员都抽中,才能进行下一轮<br>
常用方法<br>
增<br>
push(...items: T[]): number;
unshift(...items: T[]): number;
数组名[length] = 值<br>
splice(start: number, deleteCount: number, ...items: T[]): T[];
删
pop(): T | undefined;
shift(): T | undefined;
delete关键字
splice
改
通过索引修改<br>
splice
查<br>
find()
只匹配到第一个符合条件的
includes()
迭代方法(高阶函数)<br>
every()
some()
filter()
forEach()
map()
reduce()
迭代器方法<br>
entries()
keys()
values()
位置方法
indexOf(ele):返回ele在数组中的索引,返回-1表示不存在
lastIndexOf()
操作方法
concat()
slice()
splice()
排序方法
reverse()
sort()
转换方法<br>
toString()
toLocaleString()
valueOf()
join()
复制和填充方法<br>
copyWithin()
fill()
检测方法<br>
Array.isArray()<br>
数组的高级使用
最大值
最小值
平均值
求和
反转
高级排序
冒泡排序:两两相邻比较
选择排序:每次都选出最小元素的索引,然后交换
插入排序:假设第一个元素已经是一个有序数组,从第二个元素开始,将要插入的元素,插入到合适的位置上
练习<br>
创建一个对象数组,每个对象有 id、name、score 三个属性,score 是随机产生的,范围在 [0, 100]。请完成对该数据的排序。<br>要求,先以 score 从高到低排序,再以 id 从小到大排序<br>
将上面的数组长度改为100,分数范围改为[80, 100],以 score 属性进行去重<br>
数组综合练习
Map
特点<br>
键值对(key:value),虽然数组也支持,但从性能和使用上比数组要方便很多<br>
Map是以元素的添加顺序保存<br>
key不能重复
Set
特点<br>
与数组相似
不可以有重复元素
方法与Map类似
单例内置对象
Global
特点<br>
一个比较特殊的内置对象,本质上window就是Global的一个实例
JavaScript的全局变量和全局函数就是基于Global实现的,所以全局变量和函数就是Global的一个属性
常用方法<br>
交互方法
prompt()
alert()
confirm()
isNaN()
isFinite():了解
parseInt()
parseFloat()
encodeURI()了解:编码
decodeURI():解码
encodeURIComponent()了解
decodeURIComponent()
eval(),了解即可
setTimeout()
clearTimeout()
setInterval()
clearInterval()
实例<br>
window
通过this<br>
Math
常用属性
PI:圆周率
常用方法
min(...)和max(...)
...是扩展操作符,不可以直接传入数组对象<br>
apply()是函数对象的方法,不是函数返回值的方法
四舍五入
Math.ceil()
Math.floor()
Math.round()<br>
Math.fround():了解
random()<br>
练习:随机产生1~100之间整数
abs()
pow(x,y)
Date:日期类
概念:<br><br>- Date 对象用于处理日期和时间。<br>
常用方法:<br><br>- toLocaleString<br> - 获取本地的当前时间<br>- getFullYear<br> - 获取年份<br>- genMonth<br> - 获取月份,范围:0~11<br>- getDate<br> - 获取天<br>- getHours<br> - 获取小时<br>- getMinutes<br> - 获取分钟<br>- getSeconds<br> - 获取秒钟<br>- getTime<br> - 获取对应的毫秒值<br>- now<br>- 获取对应的毫秒值<br>- parse(string)<br>- 将字符串转换为毫秒值<br>
第三方工具<br>
http://momentjs.cn/
format("YYYY年MM月DD日 hh时mm分ss秒")
moment(string, format)
原始包装类型
String
长度:length属性
不可变性<br>
ECMAScript 中的字符串是不可变的(immutable),意思是一旦创建,它们的值就不能变了。要修改<br>某个变量中的字符串值,必须先销毁原始的字符串,然后将包含新值的另一个字符串保存到该变量
let lang = "Hello" + "JavaScript";<br>
常用方法
charAt()
charCodeAt()了解
concat()
字符串截取<br>
slice()、substr()<br>
substring():不支持负数
字符串位置<br>
indexOf()和lastIndexOf()
字符串包含
ES6添加了startsWith()、endsWith()和 includes()
trim()
trimStart()
trimLeft()
trimEnd()
trimRight()
replace():替换一个和replaceAll():替换所有
repeat()了解
padStart()和 padEnd()了解
大小写转换<br>
toLowerCase()和toUpperCase()
match()
综合练习
Number
常用方法<br>
valueOf()
toString()
toFixed()必须掌握
toExponential()
toPrecision()
Boolean
Function:函数
函数传参<br>
原始数据类型:值传递<br>
引用数据类型:地址传递
举例:小明在吃冰激淋(10口吃完),被原始数据类型看到了,小明买一个新的冰激淋给它吃。<br>被引用数据类型看到了,小明把自己的冰激淋给它吃一口<br>
内存示意图
RegExp:正则表达式
异常处理<br>
理解什么是程序执行完毕<br>
异常捕获<br>
可以捕获语法错误,但不可以捕获逻辑错误<br>
格式<br>
try-catch
try-finally
try-catch-finally
try:可能会抛出异常的代码一定要try中,不会抛出异常也可以写
catch:处理异常的代码块
finally:不管有没有异常都会执行
练习:页面上有一个input,id为d1,根据id获取该元素,并打印其value。如果id写错了,如何保证程序不会报红色错误
抛出异常:throw new Error()<br>
严格模式
消除Javascript语法的一些不合理、不严谨之处,减少一些怪异行为;<br>消除代码运行的一些不安全之处,保证代码运行的安全;<br>提高编译器效率,增加运行速度;<br>为未来新版本的Javascript做好铺垫。
使用
"use strict"
写在 script 第一行<br>
整个 script 都将以严格模式执行<br>
写在函数第一行
注意,"use strict" 必须写在第一行,否则无效<br>
规则
不允许使用未声明的变量
不允许删除变量或对象
不允许删除函数
不允许变量重名
不允许使用八进制
不允许使用转义字符
不允许对只读属性赋值
不允许对一个使用getter方法读取的属性进行赋值
不允许删除一个不能删除的属性
变量名不能使用 "eval" 字符串
变量名不能使用 "arguments" 字符串
变量名不能使用保留字<br>
- implements<br>- interface<br>- let<br>- package<br>- private<br>- protected<br>- public<br>- static<br>- yield<br>
不允许使用 with 语句
由于一些安全原因,在作用域 eval() 创建的变量不能被调用
禁止this关键字指向全局对象,即为 undefined<br>
DOM
概念
文档对象模型(DOM,Document Object Model)是 HTML 和 XML 文档的编程接口
DOM 表示由多层节点构成的文档,通过它开发者可以添加、删除和修改页面的各个部分
DOM树
示例
Document
Element html<br>
Element head<br>
Element title<br>
Text Sample Page<br>
Element body<br>
Element p<br>
Text Hello World!<br>
在HTML中,所有元素都是节点的父类都是Node,节点是以XML文件来说
Node类型
Node.ELEMENT_NODE(1):必须记住
Element
Node.ATTRIBUTE_NODE(2)
Attr
Node.TEXT_NODE(3):记住
Text
Node.CDATA_SECTION_NODE(4)
Node.ENTITY_REFERENCE_NODE(5)
Node.ENTITY_NODE(6)
Node.PROCESSING_INSTRUCTION_NODE(7)
Node.COMMENT_NODE(8)
Comment
Node.DOCUMENT_NODE(9):必须记住
Document
Node.DOCUMENT_TYPE_NODE(10)
Node.DOCUMENT_FRAGMENT_NODE(11)
Node.NOTATION_NODE(12)
DOM对象
获取方式
document
window.document
节点信息
nodeType:9<br>
nodeName:#document
nodeValue:null
parentNode:null
ownerDocument:null
获取元素<br>
方法
getElementById(elementId: string): HTMLElement | null;
getElementsByClassName(classNames: string): HTMLCollectionOf<Element>;
getElementsByName(elementName: string): NodeListOf<HTMLElement>;
getElementsByTagName(qualifiedName: string): HTMLCollectionOf<Element>;
选择器方法<br>
querySelector(selectors: string): E | null;
querySelectorAll(selectors: string): NodeListOf<E>;
属性
Node
readonly childNodes: NodeListOf<ChildNode>;
readonly firstChild: ChildNode | null;
readonly lastChild: ChildNode | null;
readonly nextSibling: ChildNode | null;
readonly previousSibling: ChildNode | null;
readonly parentElement: HTMLElement | null;
readonly parentNode: Node & ParentNode | null;
getRootNode(options?: GetRootNodeOptions): Node;
ParentNode
readonly children: HTMLCollection;
readonly firstElementChild: Element | null;
readonly lastElementChild: Element | null;
NonDocumentTypeChildNode
readonly nextElementSibling: Element | null;
readonly previousElementSibling: Element | null;
body: HTMLElement;了解
readonly head: HTMLHeadElement;了解
readonly forms: HTMLCollectionOf<HTMLFormElement>;获取当前页面所有表单,了解
readonly images: HTMLCollectionOf<HTMLImageElement>;了解
readonly anchors: HTMLCollectionOf<HTMLAnchorElement>;了解
readonly links: HTMLCollectionOf<HTMLAnchorElement | HTMLAreaElement>;了解
特别说明
NodeList
readonly length: number;
item(index: number): Node | null;
[index: number]: Node;
forEach(callbackfn: (value: Node, key: number, parent: NodeList) => void, thisArg?: any): void;
HTMLCollection
父类:HTMLCollectionBase
readonly length: number;
item(index: number): Element | null;
[index: number]: Element;
namedItem(name: string): Element | null;
作业:<br>
删除表格tbody标签中的内容,只留第一个标题
清空表格body中的内容,但不删除tr和td元素
删除元素
Node
removeChild<T extends Node>(oldChild: T): T; 删除元素oldChild<br>
ChildNode
remove(): void; 子元素删除自己<br>
注意:元素删除时,不要使用for循环,应该结合hasChildNodes()方法和while循环来实现
练习:删除上面中的表格中的数据,即将tr标签删除,只留第一行
创建元素
createElement(tagName: string, options?: ElementCreationOptions): HTMLElement;
createComment(data: string): Comment;了解<br>
createAttribute(localName: string): Attr;了解
createTextNode(data: string): Text;了解
附加元素<br>
Node
appendChild<T extends Node>(newChild: T): T;:在元素内的底部附加标签
insertBefore<T extends Node>(newChild: T, refChild: Node | null): T;
ParentNode
append(...nodes: (Node | string)[]): void;
prepend(...nodes: (Node | string)[]): void;
ChildNode
after(...nodes: (Node | string)[]): void;
before(...nodes: (Node | string)[]): void;
Element:重点
insertAdjacentElement(position: InsertPosition, insertedElement: Element): Element | null;
insertAdjacentHTML(where: InsertPosition, html: string): void;
类似于innerHTML
insertAdjacentText(where: InsertPosition, text: string): void;
类似于innerText
作业<br>
使用JS将一个数组中数据显示在一个表格中,不用加样式,代码不能超过120行,利用循环+数组实现
替换元素<br>
Node
replaceChild<T extends Node>(newChild: Node, oldChild: T): T;
ChildNode
replaceWith(...nodes: (Node | string)[]): void;
事件与函数初识<br>
按钮点击事件<br>
事件参数<br>
在上面的作业中,实现删除按钮功能
其它
Node
hasChildNodes(): boolean;
contains(other: Node | null): boolean;
cloneNode(deep?: boolean): Node;
textContent: string | null;
normalize(): void;了解
常用操作<br>
指定DOM元素之间文本
append()
innerText
textContent<br>
innertHTML
操作DOM表单元素的值
value
相关类<br>
Document
父类
Node
ChildNode
ParentNode
子类
HTMLDocument
常用方法<br>
createDocumentFragment()
createDocumentFragment()方法,是用来创建一个虚拟的节点对象,或者说,是用来创建文档碎片节点。它可以包含各种类型的节点,在创建之初是空的。
DocumentFragment节点不属于文档树,继承的parentNode属性总是null。它有一个很实用的特点,当请求把一个DocumentFragment节点插入文档树时,插入的不是DocumentFragment自身,而是它的所有子孙节点,即插入的是括号里的节点。这个特性使得DocumentFragment成了占位符,暂时存放那些一次插入文档的节点。它还有利于实现文档的剪切、复制和粘贴操作。
Element
父类
Node
ChildNode
ParentNode
ChildNode
Animatable
常用属性
id: string;
readonly ownerDocument: Document;
readonly tagName: string;
outerHTML: string;
返回该元素的 html 代码<br>
样式相关
readonly classList: DOMTokenList;
add
remove
toggle
className: string;
内联样式:ElementCSSInlineStyle
readonly style: CSSStyleDeclaration;
其它常用方法
属性操作<br>
getAttribute(qualifiedName: string): string | null;
getAttributeNames(): string[];
hasAttribute(qualifiedName: string): boolean;
removeAttribute(qualifiedName: string): void;
setAttribute(qualifiedName: string, value: string): void;
toggleAttribute(qualifiedName: string, force?: boolean): boolean;
子元素获取<br>
getElementsByClassName(classNames: string): HTMLCollectionOf<Element>;
getElementsByTagName(qualifiedName: string): HTMLCollectionOf<Element>;
querySelector(selectors: string): E | null;
querySelectorAll(selectors: string): NodeListOf<E>;
属性与Document类似<br>
事件相关
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
子类
HTMLElement
常用属性<br>
innerText: string;
title: string;
hidden: boolean;
常用方法
click()
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
父类
InnerHTML
innerHTML
Node
ParentNode
子类
HTMLDivElement
HTMLSpanElement
HTMLTableElement了解
常用属性<br>
readonly rows: HTMLCollectionOf<HTMLTableRowElement>;
readonly tBodies: HTMLCollectionOf<HTMLTableSectionElement>;
tHead: HTMLTableSectionElement | null;
width: string;
align: string;
常用方法
createTBody(): HTMLTableSectionElement;
createTHead(): HTMLTableSectionElement;
deleteRow(index: number): void;
deleteTHead(): void;
insertRow(index?: number): HTMLTableRowElement;
相关类<br>
HTMLTableSectionElement
insertRow(index?: number): HTMLTableRowElement;
deleteRow(index: number): void;
HTMLTableRowElement
insertCell(index?: number): HTMLTableDataCellElement;
deleteCell(index: number): void;
HTMLTableCellElement
HTMLTableDataCellElement
rowSpan: number;
colSpan: number;
readonly cellIndex: number;
HTMLFormElement
常用属性<br>
action: string;
readonly elements: HTMLFormControlsCollection;
encoding: string;
enctype: string;
readonly length: number;
method: string;
get
post
name: string;
target: string;
id
常用方法
reset(): void;
submit(): void;
获取表单元素<br>
[index: number]: Element;
[name: string]: any;
FormData
FormData 接口提供了一种表示表单数据的键值对 key/value 的构造方式,并且可以轻松的将数据通过XMLHttpRequest.send() 方法发送出去,本接口和此方法都相当简单直接。如果表单 enctype 属性设为 multipart/form-data ,则会使用表单的 submit() 方法来发送数据,从而发送数据具有同样形式。
创建对象<br>
var formData = new FormData(form)
form
可以不写,或都是 key-value 对象,如 Object 对象<br>
可以是 form 表单元素对象。但不能是 jquery 对象
常用方法
append(key, value)
添加值
key 为表单元素的 name 属性值
append(key, value, filename);
get(key)
获取表单值<br>
getAll(key)
获取表单值,返回数组
delete(key);
set(key, value);
修改值
has(key);
entries();
返回键值对
keys()
values()
forEach(callbackfn: (value: FormDataEntryValue, key: string, parent: FormData) => void, thisArg?: any): void;
Headers
创建头部信息
常用方法
- append(name: string, value: string): void;<br>- delete(name: string): void;<br>- get(name: string): string | null;<br>- has(name: string): boolean;<br>- set(name: string, value: string): void;<br>- forEach(callbackfn: (value: string, key: string, parent: Headers) => void, thisArg?: any): void;
HTMLInputElement
常用属性
name: string;
disabled: boolean;
value: string;
readOnly: boolean;
pattern: string;
required: boolean;
size: number;
表单相关<br>
readonly form: HTMLFormElement | null;
formAction: string;
formEnctype: string;
formMethod: string;
formNoValidate: boolean;
type
text/password
placeholder: string;
maxLength: number;
minLength: number;
date
datetime
datetime-local
valueAsDate: Date | null;
radio
name很重要
checked: boolean;
checkbox
checked: boolean;
hidden
看不见的
number
max: string;
step: string;
min: string;
valueAsNumber: number;
tel
email
file
files: FileList | null;
multiple: boolean;
submit
reset
button
常用方法
select(): void;
stepDown(n?: number): void;
stepUp(n?: number): void;
练习:完成验证验证
HTMLSelectElement
常用属性
autocomplete: string;
disabled: boolean;
readonly form: HTMLFormElement | null;
length: number;
multiple: boolean;
name: string;
readonly options: HTMLOptionsCollection;
required: boolean;
selectedIndex: number;
readonly selectedOptions: HTMLCollectionOf<HTMLOptionElement>;
size: number;
value: string;
常用方法
add(element: HTMLOptionElement | HTMLOptGroupElement, before?: HTMLElement | number | null): void;
item(index: number): Element | null;
namedItem(name: string): HTMLOptionElement | null;
remove(): void;
remove(index: number): void;
[name: number]: HTMLOptionElement | HTMLOptGroupElement;
相关子元素类<br>
HTMLOptionElement
defaultSelected: boolean;
disabled: boolean;
readonly index: number;
selected: boolean;
text: string;
value: string;
HTMLOptGroupElement
练习
练习:实现城市联动选择
省
市
区
HTMLFieldSetElement:了解
legend标签:指定标题
事件处理<br>
概念
- 事件源:发生事件的源头<br>- 监听器:发生事件后触发的组件<br>- 事件绑定:将事件源和监听器关联<br>- 事件:能够触发监听器的事<br>
事件流
示例
事件冒泡,IE浏览器提出
事件捕获,Netscape Communicator 团队提出
DOM2 Events 规范规定事件流分为 3 个阶段<br>事件捕获、到达目标和事件冒泡
事件处理程序
事件意味着用户或浏览器执行的某种动作。比如,单击(click)、加载(load)、鼠标悬停(mouseover)。<br>为响应事件而调用的函数被称为事件处理程序(或事件监听器)。<br>
事件处理程序的名字以"on"开头,因此 click 事件的处理程序叫作 onclick,而 load 事件的处理程序叫作 onload。有<br>很多方式可以指定事件处理程序。
事件的添加方式
html元素上,通过on事件="函数名();"<br>
不能传引用数据类型
JS获取元素,通过on事件名 = function(event){}或者指定一个函数名称<br>
JS获取元素,通过addEventListener("事件名", 回调函数, boolean)
boolean:触发类型
false - 事件在冒泡阶段执行,默认是false
true - 事件在捕获阶段执行
事件的移除方法
JS获取元素,通过on事件名 = null;<br>
JS获取元素,通过removeEventListener("事件名", 回调函数名称, boolean)
事件参数
事件处理函数,默认有一个参数event。保存有事件相关信息
readonly target: EventTarget | null;:触发事件的对象
readonly type: string:触发的事件名称
readonly cancelable: boolean:表示是否可以取消事件的默认行为
preventDefault(): void:用于取消事件的默认行为。只有 cancelable 为 true 才可以调用这个方法
stopPropagation(): void:用于立即阻止事件流在 DOM 结构中传播,取消后续的事件捕获或冒泡
stopImmediatePropagation();单击按钮时,执行第一个事件处理程序,并停止执行其余的事件处理程序:
HTML常用事件
GlobalEventHandlers
onclick:鼠标点击某个元素
dblclick:双击
onload:等待页面加载完成<br>
onfocus:获得焦点
onblur:失去焦点
onkeydown:键盘按下
通过event.keyCode获得是哪一个键
onkeyup:键盘松开
onmousedown:鼠标按下
onmousemove:鼠标移动
onmouseup:鼠标松开
onscroll
滚动事件<br>
水平滚动
垂直滚动
示例
一个页面高2000px,在1000px位置上有一个元素,顶部有一个按钮,点击滚动到中间元素位置
一个页面左边有一个垂直菜单,右边有四个高为500px的div,当页面滚动时,左边的菜单自动选中<br>
onchange
域发生改变
配合输入框,选择框,单选框,复选框
练习:实现全选、全不选、反选功能
oninput
输入事件<br>
onsubmit
提交表单
加return ture通过,false拦截
防抖和节流
这是经典的面试题,一定要掌握<br>
防抖(debounce): n 秒后在执行该事件,若在 n 秒内被重复触发,则重新计时
账号重复检查
相关事件
onchange
oninput
节流(throttle): n 秒内只运行一次,若在 n 秒内重复触发,只有一次生效
提交表单,防止重复提交<br>
滚动监听
相关事件
onscroll
onsubmit
onmousemove
升降机,就是垂直电梯<br>
电梯门10秒关一次,当每一次点击开门按钮时,那么就会重新计时,就是防抖
电梯门10秒关一次,每过10电梯就会自动关门,在10秒内按开门按钮也不会有效,那么就是节流
DOM事件中的this指向
元素onclick事件绑定:this表示window
JS通过元素属性绑定:this表示当前元素
JS通过addEventListener()方法绑定:this表示方法的调用者<br>
BOM对象
browser object model 浏览器对象模型
分类:
window
location
hash: string;
host: string;
hostname: string;
href: string;
readonly origin: string;
pathname: string;
port: string;
protocol: string;
search: string;
reload(): void;
replace(url: string): void;
练习:获取get请求的表单的参数<br>
history
readonly length: number;
back(): void;
forward(): void;
go(delta?: number): void;
navigator
screen(了解)
readonly height: number;
readonly width: number;
readonly pixelDepth: number;
window
属性
location
设置跳转页面路径
innerWidth
innerHeight
outerWidth
outerHeight
documentElement
readonly clientHeight: number;<br>readonly clientLeft: number;<br>readonly clientTop: number;<br>readonly clientWidth: number;
offsetWidth
offsetHeight
常用方法:
- alert:<br> - 显示警告框<br>- confirm:<br> - 显示确认框<br>- prompt:<br> - 显示输入框<br>- close:<br> - 关闭页面<br> - 注意:close方法:Scripts may close only the windows that were opened by it,能够关闭的页面是由该页面打开的其他页面。<br>- setinterval:设置重复动作<br>- clearinterval:清除重复动作<br>- setTimeout:设置延迟动作<br>- clearTimeout:清除延迟动作<br>
滚动控制
readonly scrollWidth: number;
scrollWidth:返回元素的整体宽度,包括由于溢出而无法展示在网页的不可见部分。
readonly scrollHeight: number;
scrollHeight :返回元素的整体高度,包括由于溢出而无法展示在网页的不可见部分。
scrollLeft: number;
指定水平滚动条的位置<br>
scrollTop: number;<br>
指定垂直滚动条的位置
scrollTo(x, y)
x:水平滚动条的位置<br>
y:垂直滚动条的位置
onscroll
滚动事件<br>
setInterval、setTimeout
setInterval(code,millisec):设置重复动作
- code:重复调用的代码(方法)<br>- millisec:重复间隔时间,单位为毫秒<br>- 返回值是重复对象<br>
clearInterval(id_of_setinterval):清除重复动作
id_of_setinterval:重复对象的id
setTimeout(code,millisec):设置延迟动作
- code:延迟调用的代码<br>- millisec:延迟时间<br>- 返回值是延迟对象<br>
clearTimeout(id_of_settimeout):请求延迟动作
id_of_settimeout:延迟对象的id
Location对象
Location对象包含有关当前URL的信息
属性
href
设置返回完整的URL
方法
reload
重新加载所在页面
History对象
History对象包含用户
常用方法
back
加载history列表中的前一个URL
forward
加载history列表中的下一个URL
go
- 加载 history 列表中的某个具体页面。<br>- go(-1):相当于back方法<br>- go(1):相当于forward方法<br>
存储
cookie
什么是cookie
作用
服务端发给客户端的唯一标识<br>
保存一些简单的数据在客户端浏览器上,比如记住密码<br>
限制<br>
构成<br>
名称(key)
不区分大小写
encodeURIComponent()
值(value)
encodeURIComponent()
域(domain)<br>
cookie的有效域
cookie跨域
路径(path)
请求 URL 中包含这个路径才会把 cookie 发送到服务器
过期时间(expires)
安全标识(secure)<br>
示例<br>
name=value; expires=Mon, 22-Jan-07 07:10:24 GMT; domain=.wrox.com; path=/; secure
使用<br>
document.cookie = name + "=" + encodeURIComponent(value) + ";expires=" + exp.toGMTString()+";path=/";
封装工具
js-cookie.js
<script src="https://cdn.jsdelivr.net/npm/js-cookie@2/src/js.cookie.min.js"></script>
set(key, value, [options])<br>
get(key)
传入key:获取指定key的value
不传入key:获取所有key信息,返回一个对象
remove(key)
jquery.cookie.min.js
<script src="https://cdn.bootcss.com/jquery-cookie/1.4.1/jquery.cookie.min.js"></script>
$.cookie('name','dumplings', {expires: 7, domain:'qq.com',path:'/'});
$.cookie("name")
$.cookie("name", null)<br>
$.removeCookie('name',{ path: '/'});
Json介绍
简介
概念
- JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。<br>- 它基于ECMAScript的 一个子集。 <br>- JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习 惯。这些特性使JSON成为理想的数据交换语言。 <br>- 易于人阅读和编写,同时也易于机器解析 和生成(网络传输速率)。<br>
语法
注意:引号只能用双引号<br>- 单一对象<br> - {"属性名1":"属性值1" , "属性名2":"属性值2"}<br>- 多个对象<br> - [{"属性名1":"属性值1" , "属性名2":"属性值2"} , {"属性名1":"属性值1" , "属性名2":"属性值2"}]<br>- 解释<br> - a.数据在键值对里面 <br> - b.数据之间由逗号分隔 <br> - c.大括号保存对象 <br> - d.中括号保存数组 <br> - e.Json值 <br> - 数字(整数或浮点数) <br> - 字符串(在双引号中) <br> - 逻辑值(true 或 false) <br> - 数组(在中括号中) <br> - 对象(在大括号中) <br> - null<br>
在JS中有一个JSON对象
stringify()
parse()
Web Storage
localStorage<br>
setItem(key: string, value: string): void;
getItem(key: string): string | null;
clear(): void;
removeItem(key: string): void;
key(index: number): string | null;
sessionStorage
练习<br>
有一个输入框和按钮,点击按钮将输入框中的数据保存,<br>关闭页面再打开时,输入框自动填入刚刚保存的数据<br>分别使用cookie和storage完成<br>
综合练习
效果图<br>
需求说明
`基于HTML+CSS+BootStrap+JavaScript实现`<br><br>- 1. 使用JS将表格中的数据显示<br><br>- 2. 添加按钮点击后,在表格的末尾添加一行,并且可以输入书名、日期、单价、数量的数据。操作栏中有一个保存按钮,还有取消按钮,保存的数据的id是当前最大的id值+1.<br><br>- 3. 数量中的+-按钮,每次点击做加一和减一处理,并且减的时候不能产生负数<br><br>- 4. 日期输入时,必须是日期输入框<br><br>- 5. 点击编辑按钮时,编辑按钮变为保存按钮,删除按钮变为取消按钮,书名、日期、单价、数量都显示一个输入框,且输入框中的数据就是当前编辑的数据内容。点击保存按钮时,将输入的内容保存到表格中,点击取消按钮恢复原样<br><br>- 6. 删除按钮点击时,一样需要提示,但只删除一条数据<br><br>- 7. 批量删除功能,在表格的第一列加一个复选框,点击时,提示是否删除选中的数据,点击是,则删除所有勾选的数据,在标题栏也有复选框,勾选时,将当页所有数据都勾选,反之,不勾选<br><br>- 8. 搜索功能,可以按书名、最低价、最高价搜索,书名搜索支持模糊搜索,不区分大小写,书名没有输入时,则显示全部数据。<br><br>- 9. 分页功能,在分页栏的左边显示当前共有多少数据,在右边显示,当前页显示多少条数据,`分页页数由数据的总数/当前页显示的数据量决定`,当前页显示的数据量用选择框显示,选择项有1, 2, 5, 10。点击不同页码时,显示相应的数据<br><br>- 10. 在页脚左边显示当前购物车的总价格,只需要显示两位小数<br><br>- 11. 不同用户登录进来,显示的数据不一样。 <br><br>- 12. 使用面向对象封装一个表格类<br>
高级<br>
RegExp:正则表达式
概念<br><br>- RegExp 对象表示正则表达式,它是对字符串执行模式匹配的强大工具。<br>
创建
let reg = new RegExp(pattern[, flags])
let reg = RegExp(pattern[, flags])
let reg = pattern[flags]
参数解析
pattern
/正则表达式/
"正则表达式"
flags
g
i
m(了解)
u(了解)
y(了解)
s(了解)
常用方法<br>
test(string: string): boolean;
exec(string: string): RegExpExecArray | null;
参考文档<br>
https://jquery.cuishifeng.cn/regexp.html
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Regular_expressions
https://www.runoob.com/regexp/regexp-syntax.html
特殊字符<br>
边界符<br>
^
$
\b:匹配一个单词边界,即字与空格间的位置。
\B:非单词边界匹配。
字符类<br>
[]
列举一些可选的字母,包含其中一个即可
/[abc]/<br>
/^[abc]$/<br>
-<br>
/[a-z]/
字符组合<br>
/[a-zA-Z0-9_-]/
^
/[^a-zA-Z0-9_-]/
|
.
/.n/
\
量词符<br>
*
重复0次或无数次<br>
+
重复1次和无数次<br>
?
重复0次或1次,但不表示只能出现一次<br>
如果出现在其它量词符后面就表示非贪婪模式。即尽可能少的去匹配<br>
{n}
重复n次<br>
{n,}
重复>=n次<br>
{n,m}
重复n到m次,包含边界,[n, m]<br>
预定义字符
\d:匹配0-9之间的任一数字,相当于[0-9]
\D:与\d相反,即[^0-9]
\w:匹配任意字母、数字和下划线,相当于[A-Za-z0-9_]
\W:与\w相反
\s:匹配空格、换行符、制表符等,相当于[\t\r\n\v\f]
\S:与\s相反
话题格式:#话题内容#,判断一个input输入框中的内容是否为话题格式,并提取其中的内容<br>
括号总结<br>
大括号<br>
中括号<br>
小括号<br>
示例:data.dat,data1.dat,data2.dat,datax.dat,dataN.dat
(pattern)
RegExp.$1~RegExp.$9
练习:9-2*5/3+7/3*99/4*2998+10*568/14<br>
取出固定模板的乘除计算部分<br>
取出不固定的模板乘除计算部分
思考:求出如上字符串的计算结果
(?:pattern)
(?=pattern)
获取/前的字符串内容,但不包含/
(?!pattern)
获取不以/结尾的字符串内容<br>
(?<=pattern)
<h1>h1标签内容</h1><div>div标签内容</div>。获取两个标签之间的内容
(?<!pattern)
常用属性
readonly source: string;
readonly global: boolean;
readonly ignoreCase: boolean;
readonly multiline: boolean;
readonly sticky: boolean;
readonly unicode: boolean;
lastIndex: number;
readonly flags: string;
构造方法属性
RegExpConstructor
lastMatch: string;
$1~$9:string
String
match(regexp: string | RegExp): RegExpMatchArray | null;
split(separator: string | RegExp, limit?: number): string[];
replace(searchValue: string | RegExp, replaceValue: string): string;
search(regexp: string | RegExp): number;
在线测试工具<br>
http://c.runoob.com/front-end/854
常用正则表达式<br>
用户名
/^[a-z0-9_-]{3,16}$/
密码
/^[a-z0-9_-]{6,18}$/
十六进制值
/^#?([a-f0-9]{6}|[a-f0-9]{3})$/
邮箱
/^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6})$/
/^[a-z\d]+(\.[a-z\d]+)*@([\da-z](-[\da-z])?)+(\.{1,2}[a-z]+)+$/
URL
/^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/
IP地址
/((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)/
/^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/
HTML标签
/^<([a-z]+)([^<]+)*(?:>(.*)<\/\1>|\s+\/>)$/
中文匹配
[\u4e00-\u9fa5]
[^\u4e00-\u9fa5]
练习
匹配整数或者小数(包括正数和负数)
-?\d+(\.\d+)?<br>
匹配年月日日期 格式2018-12-6
^[1-9]\d{0,3}-(1[0-2]|0?[1-9])-(3[01]|[12]\d|0?[1-9])$<br>
匹配qq号
[1-9]\d{4,11}
11位的电话号码
1[3-9]\d{9}
长度为8-10位的用户密码 : 包含数字字母下划线
\w{8,10}
匹配验证码:4位数字字母组成的
[\da-zA-Z]{4}或者[0-9a-zA-Z]{4}
匹配邮箱地址
[0-9a-zA-Z][\w\-.]+@[a-zA-Z0-9\-]+(\.[a-zA-Z0-9\-]+)*\.[A-Za-z0-9]{2,6}
1-2*((60-30+(-40/5)*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))<br>从上面算式中匹配出最内层小括号以及小括号内的表达式
\([^()]+\)
从类似9-2*5/3+7/3*99/4*2998+10*568/14的表达式中匹配出从左到右第一个乘法或除法
\d+[*/]\d+
Object高级部分
静态方法<br>
defineProperty(o: any, p: PropertyKey, attributes: PropertyDescriptor & ThisType<any>): any;
PropertyKey = string | number | symbol;
PropertyDescriptor
value?: any; <br>
属性值,默认为undefined
可以替换为get和set函数<br>
writable?: boolean;
值是否可以被修改,默认为false
不可与get和set函数共存
configurable?: boolean;<br>
表示属性是否可以通过 delete 删除或重新定义,是否可以修改它的特性。定义之后就无法更改<br>
默认值为true
true:可以删除或重新定义
false:不可以
enumerable?: boolean; <br>
表示属性是否可以通过 for-in 循环返回。<br>
默认值为false
true:可以遍历
false:不可以遍历
定义一个对象obj,里面有一个属性name,name的显示在一个span标签中,<br>当在开发者工具中的控制台修改了name的值时,span变化的值自动修改
defineProperties(o: any, properties: PropertyDescriptorMap & ThisType<any>): any;
PropertyDescriptorMap
[s: string]: PropertyDescriptor;
示例:Object.defineProperties(obj, {key, {}})
会覆盖掉通过defineProperty添加的属性<br>
getOwnPropertyDescriptor(o: any, p: PropertyKey): PropertyDescriptor | undefined;
getOwnPropertyDescriptors(o: T): {[P in keyof T]: TypedPropertyDescriptor<T[P]>} & { [x: string]: PropertyDescriptor };
getOwnPropertyNames(o: any): string[];
获取对象 o 上的所有属性名称,包括 enumerable 为 false 的属性名称<br>
注意,不能获取原型链上的属性名称
keys(o: object): string[];
获取对象 o 上的所有属性名称,不包括 enumerable 为 false 的属性名称<br>
values(o: {}): any[];
获取对象 o 上的所有属性的值,不包括 enumerable 为 false 的属性值<br>
entries(o: {}): [string, any][];
获取对象 o 上的所有键值对,不包括 enumerable 为 false 的键值对<br>
返回的是一个二维数组,每个数组第一个元素是 key,第二元素是 value<br>
assign(target: object, ...sources: any[]): any;
is(value1: any, value2: any): boolean;
freeze<T>(o: T): Readonly<T>;
isFrozen(o: any): boolean;
seal<T>(o: T): T;
isSealed(o: any): boolean;
preventExtensions<T>(o: T): T;
isExtensible(o: any): boolean;
create(o: object | null): any;
将o做为新对象的原型。与原型链实现的继承一致
getPrototypeOf(o: any): any;
返回指定对象的原型 ( 即, 内部[[Prototype]]属性)。
实例方法
hasOwnProperty(v: PropertyKey): boolean;
只查看对象本身,不会去原型上查找<br>
isPrototypeOf(v: Object): boolean;
用于测试一个对象是否存在于另一个对象的原型链上。
propertyIsEnumerable(v: PropertyKey): boolean;(了解)
valueOf(): Object;(了解)
toString(): string;(了解)
集合<br>
Map
特点<br>
键值对(key:value),虽然数组也支持,但从性能和使用上比数组要方便很多<br>
Map是以元素的添加顺序保存<br>
key不能重复,value可以重复
创建
const map = new Map();<br>
const m = new Map([ <br> ["key1", "val1"], <br> ["key2", "val2"], <br> ["key3", "val3"] <br>]);
长度<br>
size属性,只读
常用方法
增<br>
set(key: K, value: V): this;
删
clear(): void;
delete(key: K): boolean;
改<br>
set(key: K, value: V): this;
查
has(key: K): boolean;
get(key: K): V | undefined;
遍历
forEach(callbackfn: (value: V, key: K, map: Map<K, V>) => void, thisArg?: any): void;
不支持for-in循环
for-of
迭代器方法<br>
entries()
keys()
values()
链式写法了解<br>
Set
特点<br>
与数组相似
不可以有重复元素,有去重复的能力
常用方法
add(value: T): this;
clear(): void;
delete(value: T): boolean;
forEach(callbackfn: (value: T, value2: T, set: Set<T>) => void, thisArg?: any): void;
has(value: T): boolean;
常用属性<br>
readonly size: number;
Function:函数
内部属性<br>
arguments
保存实参数据
callee
是一个指向 arguments 对象所在函数的指针。在严格模式下,不可使用
length:实参个数
caller
函数的调用者,只能是函数对象,如果调用者不函数,则为null
了解即可
this
一般是当作构造函数使用时才考虑<br>
new.target
- 如果函数是当普通函数使用,则 new.target 的值是 undefined;<br><br>- 如果是使用 new 关键字调用的,则 new.target 将引用被调用的<br>构造函数。
通过它可以实现函数必须通过new来调用或者不能使用new来调用<br>
思考,Map 是如何实现必须通过 new Map() 来创建对象的<br>
length:形参个数
prototype:原型对象
在JS中,每个对象都有原型,不是只有函数才有
方法
apply(thisArg: any, argArray?: any): any;
会调用函数<br>
thisArg:this的指向对象<br>
argArray:数组对象,调用函数时传值的参数
call(thisArg: any, ...argArray: any[]): any;
会调用函数
thisArg:this的指向对象<br>
argArray:可变参数,调用函数时传值的参数
bind(this: Function, thisArg: any, ...argArray: any[]): any;
不会调用函数,还需要手动调用,返回一个新函数对象
比如在JS绑定点击事件使用全局函数
this指向
常规函数<br>
普通函数
直接通过函数名()调用<br>
构造函数
new 函数名()<br>
对象函数
对象名.函数名()
嵌套函数
函数中定义函数
window执行环境<br>
对象方法中的
回调函数
一个不由定义者调用的函数<br>
普通函数(对象函数)
对象函数(普通函数)<br>
对象函数(对象函数)
总结
直接通过函数名()调用的<br>
this指向window
对象名.函数名()调用的
this指向对象名
函数中的this默认是指向函数的调用者<br>
箭头函数<br>
定义在全局执行环境中<br>
箭头函数做为对象的方法定义时<br>
做为构造函数中的方法<br>
在箭头函数中,this引用的是定义箭头函数的执行环境
DOM事件对应的函数
元素onclick事件绑定:this表示window
JS通过元素属性绑定:this表示当前元素
JS通过addEventListener()方法绑定:this表示方法的调用者<br>
闭包<br>
嵌套函数,且内函数使用了外函数的变量<br>
优点
延长了外函数中的局部变量的生命周期<br>
允许函数之外操作函数中的变量<br>
缺点
如果延长的变量过多,占内存会太多<br>
用途<br>
循环创建5个定时器,定时器中打印索引<br>
let定义变量
或者传参<br>
闭包
模拟私有变量
递归函数<br>
什么是递归函数<br>
函数执行过程中调用函数本身,就是递归函数
可以做多层级数据的搜索<br>
比如,文件搜索
注意:一定写终止条件,不然就是死循环<br>
在省市县(区)三层数据中,找出所有value为包含“北”这个字的数据
作用
浅拷贝
概念:源对象和复制之后的对象中的引用数据类型指向同一个地址。
当对象的属性是引用类型时,会出现共享变量
深拷贝
深复制:源对象和复制之后的对象中的引用数据类型指向不同的地址。
lodash中的cloneDeep()
练习
使用递归函数,将多维数组变为一维数组,例如[1, [2, [3, [4]], 5]]
var 函数名 = new Function("形参列表","函数体");
函数构造器
完整对如下指令的解析<br>
回调函数练习<br>
模拟数组中的常用高阶函数
forEach<br>
filter<br>
some
every
map
reduce
find
findIndex
面向对象编程
构造函数
优点
使用统一的模板创建对象,避免重复代码。可以更好的解决引用数据类型深复制的问题
构造函数针对引用数据类型是统一使用深复制
几个概念<br>
类或构造函数
模板
对象或实例
new 构造函数();创建出来<br>
引用<br>
对象的名称,就是=左边的
匿名对象<br>
new 构造函数()<br>
一次性使用<br>
属性
实例属性<br>
this.属性名。必须写在构造函数中,否则当成使用
实例.属性名
静态属性<br>
构造函数.属性名
方法
实例方法
实例.方法名
静态方法
构造函数.方法名
缺点
构造函数存在浪费内存空间的问题,因为构造函数在处理引用数据类型时,是深拷贝模型<br>
内存示意图
思考
如何让构造函数只能通过new来调用,否则报错
练习<br>
练习一
练习二
练习三
原型
为什么<br>
解决构造函数的缺点
提供属性和方法的共享,本质上就是继承,但并不代表对象拥有了该属性
查看对象信息<br>
Console.log
查看对象内容信息
Console.dir
查看对象结构信息<br>
分类
函数原型(原型对象)<br>
函数名.prototype
对象原型<br>
对象.__proto__<br>
注意,在JavaScript中所有对象都有__proto__属性,所以构造函数原型也有__proto__属性指向其父类的构造方法<br>
原型的三种用法<br>
在原型对象上扩展
修改原型对象指向另一个构造函数创建的对象<br>
修改原型对象指向自定义对象<br>
create(o: object | null): any;
修改原型
注意:原型只会影响实例<br>
练习,通过原型给Array添加一个sum()方法,计算数组的总和,即通过数组对象.sum()就可以得到该数据的和
constructor
表示构造函数本身<br>
默认原型对象会自动提供<br>
自定义原型对象
构造函数.prototype = {}<br>
可以批量给原型对象上挂载方法和属性
通过constructor属性指定构造函数
构造函数、原型、实例默认关系图
<br>
构造函数
new<br>
创建对象
__proto__
构造函数的原型对象
prototype
constructor
原型链<br>
<br>
方法及属性的查找规则
查看对象本身是否有指定的方法,如果有就执行
如果没有,就通过 __proto__ 属性找到该对象的构造函数原型对象prototype上去找<br>
如果还没有就会通过原型链继续往查找直到Object为止
注意,原型链的层数是不固定
对象与函数原型比较
instanceof
对象 instanceof 构造函数<br>
isPrototypeOf()
构造函数.prototype.isPrototypeOf(对象)
getPrototypeOf(o: any): any;
继承实现
原型链实现<br>
优点<br>
可以实现属性和方法的继承
缺点
引用类型的属性会被所有对象共享<br>
子类型在实例化时不能给父类型的构造函数传参
盗用构造函数实现
call()和apply()可以指定this指向
优点
解决了属性继承,并且值不重复的问题
缺点
子类也不能访问父类原型上定义的方法
不能通过instanceof和isPrototypeOf()来检测父构造函数的能力<br>
组合继承:使用最多
父类函数原型上定义共享方法<br>
父类构造函数中定义属性<br>
优点
组合继承弥补了原型链和盗用构造函数的不足
是 JavaScript 中使用最多的继承模式
而且组合继承也保留了 instanceof 操作符和 isPrototypeOf()方法识别合成对象的能力
原型式继承:了解
Object.create(o: object | null, properties: PropertyDescriptorMap & ThisType<any>): any;
优点<br>
原型式继承非常适合不需要单独创建构造函数,但仍然需要在对象间共享信息的场合
缺点
与原型链实现一样
练习
定义一个Shape类,有两个属性表示宽和高<br>
创建一个自定义原型对象,有一个getArea方法,表示求面积
定义一个Square类,继承Shape类
定义一个Triangle类,继承Shape类
原型练习<br>
如何实现监听数组中如下几个方法
push
pop
unshift
shift
splice
sort
reverse
ES6<br>
类:class
定义
类声明
class 类名 {}<br>
类表达式
没有声明提升
let Person = class {}<br>
=号右边称为匿名类
支持私有变量的写法
let 类名 = (function() {return class {}})();<br>
注意:使用class定义的类,不能被当普通函数来使用<br>
类的组成
构造函数方法
constructor() {}
实例属性
在构造函数或其它函数中通过"this.属性名=值",添加<br>
在类中,但不在任何函数中,通过"属性=值"添加
get函数
set函数
实例方法
方法名() {}<br>
成员函数或成员方法,推荐使用
特点<br>
方法挂载在原型对象上,因此多个对象的方法地址共享<br>
但如果该方法被当成回调函数使用,this 指向会有问题,不过可以通过函数的bind方法解决<br>
方法名 = () => {}<br>
箭头函数写法,不推荐使用
1, 箭头函数会被babel编译到constructor里面作为this.xxx = xxx 使用, 导致原型链失效<br><br>2, 不能再子类中使用super调用父类中的箭头函数<br><br>3, 性能上箭头函数最差, 因为无法在原型中找到, 并且每个实例都含有一个该函数的拷贝<br><br>4, 尽量使用bind代替箭头函数 <br><br>5, 当作回调函数使用时 this 依然指向实例本身<br>
使用实例属性和方法时,必须通过this.属性名或方法名调用
静态
属性和方法都是挂载在函数或类本身
静态属性
static 属性名<br>
静态方法
static 方法名() {}<br>
在实例方法中可以通过 this.constructor.静态属性名或方法名 来调用<br>
练习
封装一个分页助手工具,参数有 count 和 size。传这两个参数后,<br>自动计算分页总数、第一页、最后一页、下一页、上一页。当页码和count以及size变化时,上一页和下一页会自动更新<br>
继承:extends
概念<br>
子类
也称为派生类
父类
也称为基类或超类
注意:子类在实例化时,先会创建父类实例,然后才会创建子类实例
使用方式<br>
类声明时
class 子类 extends 父类<br>
类表达式<br>
let 子类 = class extends 父类 {}<br>
注意:不支持多继承,即extends 后面跟多个类名<br>
super关键字
只能在子类中使用,而且仅限于类构造函数、实例方法和静态方法内部。
不能单独使用super,比如打印super<br>
调用 super()会调用父类构造函数,并将返回的实例赋值给 this
如果子类定义了constructor方法,且有参数,则super也必须传入参数。反之,super会自动传入参数到父类中<br>
在类构造函数中,不能在调用 super()之前引用 this
抽象类
不new的类,即无法创建实例对象
可以通过new.target实现<br>
但是抽象类可以被继承<br>
类混合
可以理解为多继承,即将多个类的的属性和方法,混入到一个对象中<br>
Object.assign(target: object, ...sources: any[]): any;
练习
定义一个函数,完成类的继承。要求如下:<br>1.&nbsp;"Chinese"类继承于"Human"类<br>2.&nbsp;"Human"类实现一个函数"getName",返回该实例的"name"属性<br>3.&nbsp;"Chinese"类构造函数有两个参数,分别为"name"、"age"<br>4.&nbsp;"Chinese"类实现一个函数"getAge",返回该实例的"age"属性<br>
0 条评论
下一页