JavaScript入门(下)详细内容
七. JavaScript-对象
1. 认识对象
发展历史
汇编语言:
- 汇编、C语言 面向过程语言
- Java、C++、javaScript、Object-c python 面向对象语言
思想:
面向过程→面向对象
面向过程:只考虑数学逻辑
面向对象:分析实体、设计实体属性功能、实体间相互作用,对生活逻辑的映射。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20//一辆车60km/h,一条路100km,问跑完时间
/*
面向过程:var hours=100/60;
面向对象:
车
速度 60km/h
功能 跑路上
路
属性
length 100km
让车真的跑在路上得出结果
*/
//贪吃蛇
/*
面向过程:坐标 蛇速度
面向对象:
蛇
食物
砖块
*/
语法
类:一类具有相同特征事物的抽象概念。(狗
对象:具体某一个个体,唯一的实例。(小白
举例
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/*
1、通过new运算符声明对象
2、通过省略new
3、对象常量赋值(使用大括号表示对象)
*/
var obj1=new Object();
var obj2=Object();
var obj3={};
//新增属性 除加前缀使用起来和普通变量无区别
obj3.username='钢铁侠'
obj3.age=18;
alert(obj3.username);
alert(obj3.age);
//通过中括号设置访问
obj3['username']='钢铁侠'
obj3['age']=18;
alert(obj3['username'])
alert(obj3['age'])
//新增方法 除加前缀使用其阿里和普通函数没有区别
obj3.show=function(){
alert("我的名字叫"+obj3.name+"。"+obj3.age+"岁")
}
obj3.show();
//通过对象常量赋值
var obj3={
username:"钢铁侠",
"age":18,
show:function(){
alert("我的名字叫"+obj3.name+"。"+obj3.age+"岁")
}
}
//delete 关键字 删除对象属性或方法
delete obj3.show;
数据结构回顾
- 基本数据类型(存储一个值
- 数组(存储多个值
- 对象(不仅可以存储多个值,还能存储函数
1 | //上面车的例子 |
2. 常用Math对象方法
万物皆为对象
数学运算函数Math对象
- Math.random() 返回0~1之间随机数
- Math.max(num1,num2) 返回较大的数
- Math.min(num1,num2) 返回较小的数
- Math.abs(num) 绝对值
- Math.round() 四舍五入(成整数,只看小数点后一位)
- Math.ceil(19.3) 向上取整
- Math.floor(11.8) 向下取整
- Math.pow(x,y) x的y次方
- Math.sqrt(num) 开平方
3. 日期对象
声明
没有传参:当前系统时间
1
2
3var d=new Date();
alert(d);//Wed Oct 09 2019 09:01:01 GMT+0800 (中国标准时间)
// GMT 格林尼治时间传参:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15/*
参数:
1.字符串 "2000-01-01"
Sat Jan 01 2000 08:00:00 GMT+0800 (中国标准时间)
2.数字(按顺序 年月日时分秒毫秒)
注:月份从0开始
var d=new Date(2000,1,1,8,30,50);
Tue Feb 01 2000 08:30:50 GMT+0800 (中国标准时间)
3.数字(毫秒数)
起点:1970/1/1 0:0:0
var d=new Date(1000);
Thu Jan 01 1970 08:00:01 GMT+0800 (中国标准时间)
*/
4. 日期对象方法
4.1. 格化式方法(了解)
方法 | 功能 |
---|---|
box.toDateString() | 特定格式显示星期几、月、日和年 |
box.totimeString() | 特定格式显示时、分、秒和时区 |
box.toLocaleDateString() | 特定地区格式显示星期几、月、日和年 |
box.toLocaleTimeString() | 特定地区格式显示时、分、秒和时区 |
box.toUTCString() | 特定格式显示完整UTC日期 |
4.2.常用方法(重点)
- set/get既能获取又能赋值 get只能获取
- set/getDate()
- 从Date对象中返回一个月中的某一天(1~31)
- getDay()
- 从Date对象返回一周中的某一天(0~6)
- set/getMonth()
- 从Date对象中返回月份(0~11)
- set/getFullYear()
- 从Date对象以四位数返回年份
- set/getHours()
- 返回Date对象的小时(0~23)
- set/getMinutes()
- 返回Date对象的分钟(0~59)
- set/getSeconds()
- 返回Date对象的秒数(0~59)
- set/getMilliseconds()
- 返回Date对象的毫秒
- set/getTime()
- 返回1970年1月1日至今的毫秒数
- getTimezoneOffset()
- 返回本地时间与格林威治标准时间(GMT)的分钟差
1 | var d = new Date(); |
4.3. 日期练习
4.3.1. 日期对象转毫秒数
1 | /* |
4.3.2. 获取两个日期之间相差的天数
1 | /* |
4.3.2. 输入n,输出n天后的时间
1 | function afterOfDate(n){ |
5. 定时器
格式:var timer = setInterval(函数,毫秒数);
功能:隔对应毫秒数,执行一次传入函数
返回值:系统分配的编号
取消定时器:clearInterval(timer);
例子:
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
27var i = 0;
function show(){
if(i==5){
clearInterval(timer);
}
document.write(i++ + "<br/>")
}
var timer = setInterval(show,1000);
//1 2 3 4 5
//======================================
var i = 0;
var show = function(){
if(i==5){
clearInterval(timer);
}
document.write(i++ + "<br/>")
}
//匿名函数
//======================================
var timer = setInterval(function(){
if(i==5){
clearInterval(timer);
}
document.write(i++ + "<br/>")
},1000);
八. JavaScript-BOM
1. 简介
browser object model(浏览器对象模型)(浏览器规则)
窗口树状结构:
window
- document
- anchors
- forms
- images
- links
- location
- frames
- history
- location
- navigator
- screen
- document
2. 系统对话框
浏览器可以通过alert()、confirm()和prompt()方法调用系统对话框向用户显示信息.
1 | //弹出警告框 |
3. open()方法
1 | /* |
第三个参数属性 | 值 |
---|---|
channelmode=yes|no|1|0 | 是否使用剧院模式显示窗口。默认为no。 |
directories=yes|no|1|0 | 是否添加目录按钮。默认yes |
funllscreen=yes|no|1|0 | 是否使用全屏模式显示浏览器。默认no。处于全屏模式的窗口必须同时处于剧院模式。 |
height=pixels | 窗口显示区高度 |
left=pixels | 窗口x坐标 |
location=yes|no|1|0 | 是否显示地址字段。默认yes |
menubar=yes|no|1|0 | 是否显示菜单栏。默认yes |
resizable=yes|no|1|0 | 窗口是否可调节尺寸。默认yes |
scrollbars=yes|no|1|0 | 是否显示滚动条。默认yes |
status=yes|no|1|0 | 是否添加状态栏。默认yes |
titlebar=yes|no|1|0 | 是否显示标题栏。默认yes |
toolbar=yes|no|1|0 | 是否显示浏览器的工具栏。默认yes |
top=pixels | 窗口y坐标 |
width=pixels | 窗口宽度 |
3. history对象
- history对象是window对象的属性,它保存用户上网记录,从窗口被打开那一刻算起
1 | 属性 |
4. location对象
1 | window下location |
1 | document下location |
九. JavaScript-DOM
1.元素节点的获取
document object model(文档对象模型)
- document:html标签里的内容
节点类型
- 元素节点
<div></div>
- 属性节点 id=‘div1’
- 文本节点 标签里的文本
- 元素节点
元素节点的获取
document.getElementById(id);
- 功能:通过id获取符合条件的元素
- 返回值:获取到的一个节点
node.getElementsByTagName(标签名);
- 功能:从node节点开始通过标签名获取符合条件的元素节点
- 返回值:伪数组/数组
node.getElementsByClassName(class名字);(IE8以下不兼容)
- 功能:从node节点开始通过class名字获取符合条件的元素节点
- 返回值:伪数组/数组
document.getElementsByName(name属性的值);
- 功能:通过name属性的值获取符合条件的元素节点
- 返回值:伪数组/数组
- 一般使用在表单元素里
document.querySelector(); IE8以下不兼容
- 返回值:一个元素节点,找到符合条件的第一个元素节点。
- 参数:字符串 CSS选择器格式字符串
document.querySelectorAll() IE8以下不兼容
- 返回值:伪数组/数组
- 参数:字符串 CSS选择器格式字符串
2.获取当前有效样式
1 | /* |
3.attribute和元素节点属性
3.1.attribute
- setAttribute()
- 添加指定的属性,并为其赋指定的值。如果这个指定的属性已存在,则仅设置/更改值。
- getAttribute()
- 返回指定属性名的属性值。
- removerAttribute()
- 删除指定的属性。
- 特点:
- 1.class访问
- 2.支持自定义属性
3.2.元素节点属性
- innerHTML:获取标签间内容
- innerText:获取标签间纯文本,不会解析标签,设置纯文本
- outerHTML:从外标签开始到外标签借宿
4.获取文本子节点
- 通过元素节点的子节点获取
- 获取元素子节点方法:
- 兼容ie6-8
- firstChild
- 访问子节点中第一个
- lastChild
- 访问子节点最后一个
- nextSibling
- 下一同级节点
- previousSibling
- 上一同级节点
- firstChild
- 兼容ie9-10 chrome firefox
- 只获取元素节点
- firstElementChild
- 第一个节点
- lastElementChild
- 最后一个节点
- nextElementSibling
- 下一同级节点
- previousElementSibling
- 上一同级节点
- childNodes
- 访问当前节点下所有子节点
- 获取:childNodes[]
- 特点:回车也会被当作节点
- children
nodeType | nodeName | nodeValue | |
---|---|---|---|
元素节点 | 1 | 标签名 | null |
属性节点 | 2 | 属性名 | 属性值 |
文本节点 | 3 | #text | 文本内容 |
5.属性节点attributes
- 获取当前元素节点上的素有属性节点
- 返回值:集合对象
- 集合:无序、不重复
获取其中某一个节点
- getNamedItem(“title”) 获取节点
- 节点.attributes.getNamedItem(“title”).nodeName; //title 获取属性名
- 节点.attributes.getNamedItem(“title”).nodeType; //2 获取属性类型
- 节点.attributes.getNamedItem(“title”).nodeValue; //hello 获取属性值
- 繁琐,可以简化
- 节点.attributes[“title”].nodeName; //title 获取属性名
- 节点.attributes[“title”]..nodeType; //2 获取属性类型
- 节点.attributes[“title”]..nodeValue; //hello 获取属性值
6. DOM节点操作
document.write()
- 覆盖页面上原有内容
createElement()
- 功能:创建一个元素节点
- 格式:document.createElement()
- 参数:标签名
- 返回值:创建好的这个节点
appendChild()
- 功能:将node2节点插入到node1节点子节点的末尾
- 格式:node1.appendChild(node2);
createTextNode()
- 功能:创建文本节点(纯文本,写标签也不解析)
- 格式:document.createTextNode(文本)
insertBefore()
- 功能:将box2添加到box1前面
- 格式:box1.parentNode.insertBefore(box2,box1);
- 注意:必须用box1的父节点进行调用
replaceChild()
- 功能:用box2节点将box1节点替换掉
- 格式:box1.parentNode.replaceChild(box2,box1);
- 注意:必须用box1的父节点进行调用
cloneNode()
- 功能:克隆node节点,子节点和行间内容不克隆
- 格式:node.cloneNode();
- 功能2:克隆node节点,子节点和行间内容也克隆
- 格式:node.cloneNode(true);
- 返回值:克隆出来的新节点
removeChild()
- 功能:删除box节点
- 格式:(box.parentNode).removeChild(box)
- 注意:必须用box的父节点进行调用
7. this关键字
概念:只要封装函数,任何一个函数系统都会内置一个叫做this的变量,this变量存储的是地址,当前函数主人的地址。函数主人通过上下文判断。this类似于现实生活中,用到的“我”。
常用情况:
1
2
3
4
5
6
7
8var person={
username:"钢铁侠",
sex:"男",
show: function(){//函数主人为person
alert(person.username);
alert(this.username);//2个结果一样
}
}1
2
3
4
5function show(){
alert(this);
}
show();//全局函数 函数主人默认为window
window.show();1
2
3
4
5
6
7
8window.onload=function(){
var oBtn=dcument.getElementById("btn1");
//给页面上btn1的一个对象添加了一个函数
//函数主人为当前按钮 this指向oBtn
oBtn.onclick=function(){
alert(this);
}
}
8. offset方法
- offsetWidth
- offsetHeight
- 获取元素宽高 不带px
- boorder和padding计算在内
- offsetLeft
- offsetTop
- 获取眼睛能看到的实际距离第一个有定位的父节点的距离。
- 不带px margin计算在内
8.1. 获取元素相对于视口的位置
- getBoundingClientRect()
- getBoundingClientRect用于获取某个元素相对于视窗的位置集合。集合中有top, right, bottom, left等属性。
- 返回值:
- div.getBoundingClientRect().top:名为div元素上边到视窗上边的距离;
- div.getBoundingClientRect().right:名为div元素右边到视窗左边的距离;
- div.getBoundingClientRect().bottom:名为div元素下边到视窗上边的距离;
- div.getBoundingClientRect().left:名为div元素左边到视窗左边的距离;
9. 文档碎片
1 | /* |
10. 数组和对象的遍历方法
数组遍历:
for循环
for…in快速遍历 (效率高无判断
forEach
1
2
3
4
5
6
7
8
9
10
11
12var arr[10,20,30,40]
for(var i=0;i<arr.length;i++){
document.write(i+","+arr[i]);
}
for(var i in arr){
document.write(i+","+arr[i]);
}
arr.forEach(function(item,index,arr){
document.write(indexi+","+item);
});
对象遍历:
for…in
1
2
3
4
5
6
7
8var person={
username:"钢铁侠",
age:18,
sex:"男"
}
for(var i in person){
document.write("属性名:"+i+"属性值:"+person[i])
}
九. JavaScript-事件
1.事件和事件类型
1.1. 什么是事件:
- 事件是发生并得到处理的操作,即事情来了,然后处理,例如:
- 电话铃响起(事件发生),接电话(处理)
- 同学举手(事件发生),解答(处理)
- 按钮被点击(事件发生),对应一个函数来处理(处理)
1.2. 事件绑定方式
JavaScript事件是由访问Web页面的用户引起的一系列操作,例如:用户点击。当用户执行某些操作的时候,再去执行一系列代码。
JavaScript有两种事件模型:内联模型、外联/脚本模型。
内联模型:
这种模型是最传统接单的一种处理事件的方法。在内联模型中,事件处理函数是HTML标签的一个属性,用于处理指定事件。虽然内联在早期使用较多
<button onclick='btn();'> </button>
1
2
3
4
5
6
7
8
- 外联模型:
- ```javascript
var btn=document.getElementById("btn1");
btn.onclick=function(){
alert("外连模式")
}绑定格式:
- 元素节点.on+事件类型=匿名函数。
- click 事件类型
- onclick 事件处理的函数
实际开发中我们希望js代码和html css是分离的 所以推荐使用外联模型。
1.3. 事件类型的种类
一、鼠标事件(可以绑定在任何元素节点上)
事件名 | 事件详情 |
---|---|
click | 单击 |
dblclick | 双击 |
mouseover | 鼠标移入 |
mouseout | 鼠标移出 |
mousemove | 鼠标移动(不停触发 |
mouseenter | 鼠标移入 |
mouseleave | 鼠标移出 |
mouserleave和mouseout的区别
mouseleave是当鼠标指针离开了目标元素以及目标元素的所有子元素以后才会触发。
而mouseout是只要鼠标指针离开了目标元素或者目标元素的所有子元素中的任何一个就会被触发,即使鼠标指针还在目标元素内。也就是离开子元素后,mouseout事件会冒泡到父元素上。直到取消了冒泡或者到达了最外层根元素,才会停止冒泡。
https://www.w3school.com.cn/tiy/t.asp?f=jquery_event_mouseleave_mouseout
mouseenter与mouseove同理
- mouseenter经过子节点不会重复触发
- mouserover经过子节点会重复触发
二、键盘事件(表单元素、全局window)
- keydown
- 键盘按下(不放手 一直触发
- keyup
- 键盘抬起
- keypress
- 键盘按下(只支持字符键,例如数字,英文字符键)
三、HTML事件
1. window事件
- load
- 页面加载完以后触发
- unload
- 当页面解构的时候触发(刷新,关闭)仅兼容ie
- scroll
- 页面滚动
- resize
- 窗口大小发生变化
2. 表单事件
- blur
- 失去焦点
- foucs
- 获取焦点
- select
- 当我们在输入框内选中文本的时候触发
- change
- 当我们对输入框的文本进行修改并且失去焦点的时候
- 必须添加到form元素的事件
- submit
- 当我们点击submit的按钮才能触发
- reset
- 当我们点击reset的按钮才能触发
2. 事件对象和事件对象属性
2.1. 事件对象
引例:番茄炒蛋 番茄+鸡蛋+条例炒出来的味道是全新的味道,不是番茄也不是鸡蛋的味道了
事件绑定:
- 元素节点.on + 事件类型=匿名函数;
系统会在事件绑定完成的时候,生成一个事件对象,将事件对象当作第一个参数传入
触发事件的时候,系统会自动去调用事件绑定的函数
1
2
3
4
5
6
7
8
9function show(){
alert(arguments.length);//1
alert(arguments[0]);//object MouseEvent
alert("hello world");
}
window.onload=function(){
var btn=document.getElementById("btn1");
btn.onclick=show;
}可以设置一个形参,传入事件对象的时候可以通过形参拿到 ie8以下不兼容
1
2
3
4
5
6
7
8
9
10
11
12
13function show(ev){
//浏览器兼容
var ev = ev || window.event
alert(arguments.length);//1
alert(arguments[0]);//object MouseEvent
alert(ev)//object MouseEvent
alert("hello world");
}
window.onload=function(){
var btn=document.getElementById("btn1");
btn.onclick=show;
}最终写法:
1
2
3
4
5
6
7
8window.onload=function(){
var btn=document.getElementById("btn1");
btn.onclick=function(ev){
//事件对象获取,固定写法
var ev=ev||window.event;
alert(e);
}
}
2.2. 事件对象属性
- button属性
- 0 按下鼠标左键
- 1 滚轮
- 2 右键
获取当前鼠标位置:区别(原点位置不同)
- clientX clientY
- 可视窗口的左上角为原点
- pageX pageY
- 整个页面的左上角(包含滚动出去的距离)
- screenX screenY
- 电脑屏幕的左上角
获取功能键:
shiftKey
- 按下shift键,为true,默认为false
altKey
- 按下alt键,为true,默认为false
ctrlKey
- 按下ctrl键,为true,默认为false
metaKey
- windows系统 按下windows(开始)键,为true
- macos系统 按下command键,为true
可以和别的操作进行组合,形成一些快捷键操作。
获取键码
- keyCode (兼容ie) 和 which
- 格式:var which = e.which || e.keyCode;
- 返回值:大写字母的ASCII码值。不区分大小写。
- 只在keydown下支持
获取字符码
- charCode (兼容ie) 和 which
- 格式:var which = e.which || e.charCode;
- 返回值:区分大小写的ASCII码值。
- 只在keypress下支持,只支持字符键。
3. 目标对象和事件冒泡
3.1. 目标对象target
概念:是事件对象的属性,代表触发对象
- 触发对象:事件由谁而起的
兼容IE8:window.event.srcElement;
例子:
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...
<script>
window.onload=function(){
var li=doucment.getElementById("li1")
li.onclick=function(ev){
var e=ev||window.event;
var target = e.target||window.event.srcElement;
alert(target.innerHTML);//1111
}
var ul=doucment.getElementById("ul1")
li.onclick=function(ev){
var e=ev||window.event;
var target = e.target||window.event.srcElement;
//点击内容2222的li
alert(this.tagName);//ul this指向函数主人ul
alert(target.innerHTML);//2222 由li而起的
//就好像隔了一层纸打了你一下,然后你叫了一声,但是我打的是纸,触发对象是纸,疼的是你。
}
}
</script>
...
<body>
<ul id='ul1'>
<li id='li1'>1111</li>
<li>2222</li>
</ul>
</body>
...
3.2. 事件冒泡与捕获
冒泡:一个页面中的多个dom如果呈现父子类关系,并且都绑定了事件,则会有事件冒泡的情况发生,从最里面的dom冒泡到外层,由里向外逐级触发。
捕获:冒泡反过来,由外向里逐级触发
阻止事件冒泡:
- event.stopPropagation()
- event.cancelBubble=true;
1
2
3
4
5
6
7function stopbUBBLE(e){
if(e.stopPropagation){
e.stopPropagation();
}else{
e.cancelBubble=true;
}
}
4.阻止默认行为
1.阻止官方右键菜单
1 | window.onload=function(){ |
2.阻止超链接跳转
1 | link.onclick=function(evt){ |
案例:自定义右键菜单,跳转链接阻止加操作
5.实现拖拽使用到的事件
拖拽:
mousedown
- 记录鼠标按下位置和被拖拽物体相对距离
mousemove
- 一直保持相对距离
mouseup
- 取消拖拽
6. 事件委托
1 | window.onload=function(){ |
1 | /* |
7. 事件监听器
1 | //传统事件绑定格式 |
事件监听器兼容
1 | function addEvent(node,evenType,funcName){ |
案例:生成表格,放大镜
十. JavaScript-正则表达式
1. 概念
- 用途
- 假设用户需要在HTML表单中填写姓名、地址、出生日期等。那么在将表单提交到服务器进一步处理之前,JavaScript程序会检查表单确认用户确实输入了信息并且这些信息是符合要求的。
- 概念:
- 正则表达式(regular expression)是一个描述字符模式的对象。ECMAScript的RegExp类表示正则表达式,而String和正则表达式都定义了进行强大的模式匹配和文本检索与替换的函数
2. 创建正则表达式
通过new去声明正则表达式
- 参数1:正则表达式主体(字符串
- 参数2:修饰符 i/g
1
2var box1=new RegExp("hello","ig");
alert(box1) // /hello/gi省略new运算符声明正则表达式
1
2var box1=RegExp("hello","ig");
alert(box1) // /hello/gi通过常量赋值声明正则表达式
1
2var box1=/hello/gi;
alert(box1) // /hello/gi
3. 正则表达式方法
- test
- 格式:正则.test(字符串)
- 功能:在字符串中匹配这个正则是否存在
- 返回值:成功返回true,失败返回false
- exec
- 格式:正则.exec(字符串)
- 功能:在字符串中匹配这个正则是否存在
- 返回值:返回匹配到的字符串,成功返回数组,失败返回null
4.可使用正则表达式的字符串方法
match()
- 格式:字符串.match(正则);
- 功能:字符串中匹配是否有符合的字符串
- 返回值:成功返回装有匹配到字符串的数组,失败返回null
replace()
格式:字符串.replace(旧字符串/正则,新字符串);
功能:新替换旧
返回值:替换成功的新字符串
1
2
3var str="how are Are ARE you";
var newStr=str.replace(/are/ig,"*");
alert(newStr) // how * * * you
split()
格式:字符串.replace(分隔符/正则);
功能:用分隔符将原字符串进行分割
返回值:分割剩下的子串组成的数组。
1
2
3var str="how are Are ARE you";
var newStr=str.split(/are/i);
alert(arr);//how,,,you
search()
格式:字符串.search(字符串/正则);
功能:找到符合字符串第一次出现位置
返回值:找到返回>=0下标,否则返回-1
1
2
3var str="how Are are ARE you";
var newStr=str.search(/are/i);
alert(arr);//4
5.元字符
- 概念:在正则表达式中有特殊含义的字符串
5.1. 常用元字符
元字符 | 匹配情况 |
---|---|
. | 匹配除换行符外任意单个字符 |
[a-z0-9] | 匹配括号中字符集任意字符 |
[^a-z0-9] | 匹配不在括号中字符集的字符 |
\d | 匹配数字 |
\D | 匹配非数字同[ ^0-9]相同 |
\w | 匹配字母数字下划线 |
\W | 匹配非字母数字下划线 |
元字符 | 匹配情况 |
---|---|
x? | 匹配0或1个x |
x* | 匹配0或任意多个x |
x+ | 匹配至少一个x |
(xyz)+ | 匹配至少一个xyz |
x{m,n} | 匹配最少m个、最多n个x |
元字符 | 匹配情况 |
---|---|
\s | 匹配空白字符、空格、制表符和换行符 |
\S | 匹配非空白字符 |
\0 | 匹配null字符 |
\b | 匹配空格字符 |
\f | 匹配换页符 |
\n | 匹配换行字符 |
\r | 匹配回车字符 |
\t | 匹配制表符 |
元字符 | 匹配情况 |
---|---|
^ | 必须以这个正则开头 |
$ | 必须以这个正则结尾 |
| | 两项之间的一个选择 |
- 案例:输入框密码框验证
十一. localStorage
1.什么是localStorage
loacalStorage本地存储对象
在HTML5中,新加入了一个loaclStorage特性,这个特性作为本地存储使用,解决了cookie存储空间不足问题(每条cookie的存储空间为4k),localStorage中一般浏览器支持的是5M大小,这个在不同浏览器中localStoarage会有所不同。
2.localStorage优势与局限
- localStorage的优势
- localStorage拓展了cookie的4K限制
- localStorage可以将第一次请求的数据直接存储到本地,相当于5M大小针对前端页面的数据库,相比cookie可以节约带宽,高版本浏览器才支持
- localStorage的局限
- 浏览器大小不统一,ie8以上才支持
- 值类型为string,相比常见的JSON对象类型需要转换
- 在浏览器隐私模式下不可读取
- 本质是对字符串读取,存储内容多会消耗内存空间,导致页面变卡
- 不能被爬虫抓取到
- 永久性存储
3.cookie
- 可以设置过期时间
- 最大可以存4KB
- 每一个域名下最多可以存储50条数据
4.sessionStorage
- 结合后端
- 保留一次对话
5.localStorage方法
setItem(name,value);
getItem(name);
removeItem(name);
1
2
3
4
5
6
7
8
9
10
11
12
13
14if(!window.localStorage){
alert("当前页面不支持localStorage")
}else{
//设置
localStorage.setItem("a","1");
localStorage.b='2';
localStorage["c"]='3';
//获取
console.log(localStorage.getItem("b"));
console.log(localStorage.c);
console.log(localStorage['a']);
//删除
localStorage.removeItem("a");
}
十二. 强制改变this指向函数
this回顾
每一个函数的内置变量 指向当前函数主人
全局函数this指向window对象
对象内的函数的this指向对应名称对象
1
2
3
4
5
6var person={
name:"123";
show:function(){
this.name;//this指向person
}
}绑定事件的函数中的this指向绑定函数的对象
call()
- 格式:函数名.call();
- 参数1:传入改函数this指向的对象,传入什么强制指向什么
- 参数2:将原函数的参数往后顺延一位。
apply()
格式:函数名.apply();
参数1:传入改函数this指向的对象,传入什么强制指向什么
参数2:数组,放入我们原有所有参数
apply()应用小技巧
1
2var arr=[1,2,3,4,5]
alert(Math.min.apply(null,arr))
bind() 预设this指向
1
2
3
4
5
6function show(x,y){
alert(this);
alert(x+","+y);
}
var res=show.bind("bind");//不调用
res(40,50);//bing 40,50三者区别点:
call和apply会调用函数,并改变函数内部this指向
call和apply传递的参数不一样,call传递参数aru1,aru2…形式,apply必须数组形式[arg]
bind不会调用函数,可以改变函数内部this指向。
主要应用场景:
- call常做继承
- apply经常跟数组有关系,比如借助math对象实现数组最大值最小值
- bind不调用函数,但想改变this指向,比如改变定时器内部的this指向
十三. let和const关键字
1. let关键字
1 | //类似var 但是所声明的变量,只在let命令所在的代码块内有效。 |
2. const关键字
1 | /* |
十四. 箭头函数
- 箭头函数:另一种函数写法
1 | function add(x){ |
与数组方法结合使用
1
2
3
4
5
6
7
8
9
10//filter 过滤
var arr=[1,2,3,4,5,6];
var newArr=arr.filter(function(item){
return item>2;
})
alert(newArr);//3,4,5,6
//转换成箭头函数
var newArr=arr.filter(item => item>2);
//====================
var newArr=arr.map(item=>item*1.3);注意:
- 箭头函数不能用new
- 返回值是对象一定要加();
- 箭头函数中的this指向上一层函数主人,没有上一层指向window
十五. 解构和ECMA6字符串
1. 解构
1 | var x=10,y=20,z=30; |
2. ECMA6字符串
1 | /* |
十六.ECMA6新增数组方法和合并对象
1. 新增数组方法
1 | /* |
2. 合并对象
- Object.assign
1 | var obj1={ |
- 应用
1 | //为对象添加属性 |
十六.ECMA6集合
集合:
- 不重复
- 无序
Set
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
31let imgs=new Set();
imgs.add(100);
imgs.add(100);//重复 添加不进去
imgs.add("hello");
imgs.add("hello");//重复 添加不进去
imgs.add(true);
imgs.add(new String("world"));
imgs.add(new String("world"));//每次新建一个 添加的进去
/*
集合遍历
for...of
*/
for(let item of imgs.keys()){
console.log(item);
}
for(let item of imgs.values()){
console.log(item);
}
for(let item of imgs.entries()){
console.log(item);
}
/*
利用集合去重
*/
var set=new Set([2,3,3,4,4]);
var arr=[...set];//将数据结构展开成数组
var arr=[1,1,2,2,3,3];
arr=[...new Set(arr)];Map映射
- 键值不一致
1
2
3
4
5
6
7
8
9
10
11
12//声明
let map =new Map();
//添加
map.set("张三","打渔");
map.set("李四","种地");
map.set("王五","挖煤");
//取值
alert(map.get("王五"));
//遍历for of
for(let [key,value] of map){
console.log(key,value);
}
十七.数组遍历回顾与补充
数组
for循环
1
2
3
4var arr=[10,20,30,40,60];
for(var i=0;i<arr.length;i++){
document.write(arr[i]+","+i);
}for…in
1
2
3for(var i in arr){
document.write(arr[i]+","+i);
}foreach
1
2
3arr.forEach(function(item,index){
document.write(item+","+index);
})for…of
1
2
3
4for(var item of arr){
//item是当前遍历元素
document.write(item);
}
对象
for…in
1
2
3
4for(var attr in obj){
//attr是obj对象的属性
document.write(attr+","+obj[attr]);
}
集合
- for …of
十八.构造函数(封装)
1 | /* |
十九.继承和多态
1. 继承
父类
1
2
3
4
5
6
7function Person(name){
this.name=name;
this.sum=function(){
alert(this.name)
}
}
Person.prototype.age=10;原型链继承
1
2
3
4
5
6function Per(){
this.name="ker";
}
Per.prototype=new Person();//原型链继承
var per1=new Per();
console.log(per1.age);//10概念:让新实例的原型等于父类的实例
特点:实例可继承的属性有:实例的构造函数的属性,父类构造函数属性,父类原型的属性。(新实例不会继承父类实例的属性!)
缺点:
新实例无法向父类构造函数传参
继承单一
所有新实例都会共享父类实例的属性。
借用构造函数继承
1
2
3
4
5
6
7function Per(){
Person.call(this,"jer");//借用构造函数继承
this.age=12;
}
var per1=new Per();
console.log(per1.name);//jer
console.log(per1.age);//12重点:用.call()和.apply()将父类构造函数引入子类函数(在子类函数中做了父类函数的自执行(复制))
特点:- 只继承了父类构造函数的属性,没有继承父类原型的属性。
- 解决了原型链继承缺点1、2、3。
- 可以继承多个构造函数属性(call多个)。
- 在子实例中可向父实例传参。
缺点:
- 只能继承父类构造函数的属性。
- 无法实现构造函数的复用。(每次用每次都要重新调用)。
- 每个新实例都有父类构造函数的副本,臃肿。
组合继承(组合上面2种)(常用)
1
2
3
4
5
6
7function Per(name){
Person.call(this,name);//借用构造函数
}
Per.prototype=new Person();//原型链继承
var per=new Per("ker");
console.log(sub.name);//gar 继承构造函数属性
console.log(sub.age);//10 继承父类原型属性重点:结合了两种模式的优点,传参和复用
特点:
- 可以继承父类原型上的属性,可以传参,可复用。
- 每个新实例引入的构造函数属性是私有的。
缺点:调用了两次父类构造函数(耗内存),子类的构造函数会代替原型上的那个父类构造函数。
原型式继承
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17function Person(name){
this.name=name;
this.sum=function(){
alert(this.name)
}
}
Person.prototype.age=10;
//先封装一个函数容器,用来输出对象和承载继承的原型
function content(obj){
function F(){}
F.prototype=obj;//继承传入参数
return new F();//返回函数对象
}
var sup=new Person();//拿父类实例
var sup1=content(sup);
console.log(sup1.age);//10 继承了父类函数属性重点:用一个函数包装一个对象,然后返回这个函数的调用,这个函数就变成了个可以随意增添属性的实例或对象。object.create()就是这个原理。
特点:类似于复制一个对象,用函数来包装。
缺点:
- 所有实例都会继承原型上的属性。
- 无法实现复用。(新实例属性都是后面添加的)
寄生式继承
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18//先封装一个函数容器,用来输出对象和承载继承的原型
function content(obj){
function F(){}
F.prototype=obj;//继承传入参数
return new F();//返回函数对象
}
var sup=new Person();//拿父类实例
function subobject(obj){
var sub=content(obj);
sub.name="gar";
return sub;
}
var sup2=subobject(sup);
//这个函数经过声明之后成了可增添属性的对象
console.log(typeof subobject);//function
console.log(typeof sup2);//object
console.log(sup2.name);//"gar",返回sub对象 继承了sub的属性重点:就是给原型式继承外面套了个壳子。
优点:没有创建自定义类型,因为只是套了个壳子返回对象(这个),这个函数顺理成章就成了创建的新对象。
缺点:没用到原型,无法复用。
寄生组合式继承(常用)
寄生:在函数内返回对象然后调用
组合:1、函数原型等于另一个实例。2、在函数中用apply或call引入另一个构造函数,可以传参
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21//寄生
function content(obj){
function F(){}
F.prototype=obj;
return new F();
}
//content就是F实例的另一种表示法
var con=content(Person.peototype);
//con实例(F实例)的原型继承了父类函数的原型
//上述更像是原型链继承,只不过只继承了原型属性
//组合
function Sub(){
Person.call(this);//继承了父类构造函数属性
}//解决了组合式量词调用构造函数属性缺点
//重点:
Sub.prototype=con;//继承了con实例
con.constructor=Sub;//一定要修复实例
var sub1=new Sub();
//Sub的实例就继承了构造函数属性,父类实例,con的函数属性
console.log(sub1.age);//10;重点:修复了组合继承的问题
2.多态
多态背后的思想是将”做什么“和”谁去做以及怎样去做分开“。
非多态代码示例
1
2
3
4
5
6
7
8
9
10
11var makeSound = function(animal) {
if(animal instanceof Duck) {
console.log('嘎嘎嘎');
} else if (animal instanceof Chicken) {
console.log('咯咯咯');
}
}
var Duck = function(){}
var Chiken = function() {};
makeSound(new Chicken());
makeSound(new Duck());多态代码实例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15var makeSound = function(animal) {
animal.sound();
}
var Duck = function(){}
Duck.prototype.sound = function() {
console.log('嘎嘎嘎')
}
var Chicken = function() {};
Chiken.prototype.sound = function() {
console.log('咯咯咯')
}
makeSound(new Chicken());//咯咯咯
makeSound(new Duck());//嘎嘎嘎
3.__ proto __ 和instanceof关键字
- __ proto __ :构造函数构造出来的对象,有一个属性
__proto__
,指向构造出这个对象的构造函数的原型。 - instanceof:instanceof运算符用来判断一个构造函数的prototype属性所指向的对象是否存在另外一个要检测对象的原型链上
二十. ECMA6的class语法
传统构造函数写法
1
2
3
4
5
6
7
8function Person(name,sex,age){
this.name=name;
this.sex=sex;
this.age=age;
}
Person.prototype.show=function(){
alert('我的名字叫${this.name},今年${this.age}岁,${this.sex}');
}ECMA6 class
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22class Person{
constructor(name,sex,age){
this.name=name;
this.sex=sex;
this.age=age;
}
show(){
alert('我的名字叫${this.name},今年${this.age}岁,${this.sex}');
}
}
//继承
class Worker extends Person{
construtor(name,sex,age,job){
//继承父级属性
super(name,sex,age);
this.job=job;
}
showJob(){
alert("我的工作是"+this.job);
}
}