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