JavaScript面向对象笔记(4)
一、正则表达式
1.正则表达式概述
Regular Expression
:是用于匹配字符串组合的模式,再javaScript中,正则表达式也是对象。
正则表达式通常被用来检索、替换某个模式(规则)的文本。例如:表单校验,用户名只能输入英文字母、数字或下划线。昵称输入框中可以匹配中文。
此外正则表达式还可以替换一些敏感词。或者从字符串中获取我们想要特定部分(字符串内容提取)等。
其它语言也有正则表达式,本阶段我们主要利用的是javaS次日普通的正则表达式进行表单验证。
2.正则表达式特点
- 灵活性、逻辑性和功能性非常的强
- 可以迅速地用极简单的方式达到字符串的复杂控制
- 对于刚接触的人来说,上手也是比较容易
3.正则表达式再js中的使用
3.1 正则表达式的创建
在javaScript中,可以通过两种方式创建正则表达式
方式一
var reg = new RegExp(正则表达式)
方式二
利用字面量的方式创建正则表达式
var reg = /正则表达式/
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>01正则表达式的创建方式</title>
</head>
<body>
<script>
//1.利用RegExp对象来创建正则表达式
var reg1 = new RegExp(/123/);
console.log(reg1);
//2.利用字面量的方式创建正则表达式
var reg2 = /123/
console.log(reg2);
//3. 在正则表达式中有一个test方法可以用来检测字符串是否符合正则表达式
console.log(reg1.test(123));
console.log(reg1.test('abc'));
</script>
</body>
</html>
3.2 正则表达式中的特殊字符
3.2.1 正则表达式的组成
MDN文档:
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Regular_expressions
正则表达式中的边界符(位置符),用来提示字符所在的位置,主要有两个位置符
边界符 | 说明 |
---|---|
^ | 表示匹配行首的文本(以谁开始) |
$ | 表示匹配行尾的文本(以谁结束) |
如果上面的两个在一起,表示必须是精确匹配
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>02边界符</title>
</head>
<body>
<script>
//正则表达式里面不需要加引号,不管是hi数字型还是字符串型
// /abc/ 表达的意思是含有abc这个字符串都返回true
var reg = /abc/;
console.log(reg.test('abc')); //true
console.log(reg.test('abcd')); //true
console.log(reg.test('aabcd')); //true
//^表示匹配行首的文本(以谁开始)
var reg1 = /^abc/
console.log(reg1.test('abc')); //true
console.log(reg1.test('abcd')); //true
console.log(reg1.test('aabcd')); //false
//$表示匹配行尾的文本(以谁结束)
var reg1 = /abc$/
console.log(reg1.test('abc')); //true
console.log(reg1.test('abcd')); //false
console.log(reg1.test('aabcd')); //false
console.log(reg1.test('aabc')); //true
</script>
</body>
</html>
3.3 字符串类
字符串雷柏哦是有一系列字符可以选择,只要匹配其中的一个就可以了,所有可供选择的字符都放在方括号内
3.3.1 [] 方括号
表示一系列字符可供选择,只要匹配其中的一个就可以了
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>03方括号</title>
</head>
<body>
<script>
// var reg = /abc/ 只要包含abc就可以了
// 字符类: [] 表示有一系列字符可供选择,只要匹配其中的一个就可以了返回true
var reg = /[abc]/
console.log(reg.test('admin')); //true
console.log(reg.test('baby')); //true
console.log(reg.test('color')); //true
console.log(reg.test('red')); //false
console.log('==========================================');
// 三选一, 开始字符是三选一,结束的字符也是三选一
// 如果加了^ 和 $ 则限制了待校验的字符串的长度
var reg1 = /^[abc]$/
console.log(reg1.test('aa')); //false
console.log(reg1.test('a')); //true
console.log(reg1.test('b'));//true
console.log(reg1.test('c'));//true
console.log(reg1.test('abc'));//false
console.log('==========================================');
// 26个英文字母任何一个就可以用 a-z A-Z 0-9
var reg2 = /^[a-z]$/
console.log(reg2.test('a')); //true
console.log(reg2.test('B')); //false
console.log(reg2.test(8)); //false
console.log(reg2.test('-')); //false
console.log(reg2.test(' ')); //false
console.log(reg2.test('!')); //false
console.log('==========================================');
//字符串组合
var reg3 = /^[a-zA-Z0-9_-]$/
console.log(reg3.test('a')); //true
console.log(reg3.test('B')); //true
console.log(reg3.test(8)); //true
console.log(reg3.test('-')); //true
console.log(reg3.test(' ')); //false
console.log(reg3.test('!')); //false
console.log('==========================================');
//如果括号中出现了多个^,表示取反的意思,千万不要和边界符 ^混淆
var reg4 = /^[^a-zA-Z0-9_-]$/
console.log(reg4.test('a')); //false
console.log(reg4.test('B')); //false
console.log(reg4.test(8)); //false
console.log(reg4.test('-')); //false
console.log(reg4.test(' ')); //true
console.log(reg4.test('!')); //true
</script>
</body>
</html>
3.4 量词符
两次赴用来设定某个模式出现的次数
量词 | 说明 |
---|---|
* | 重复0次或者是多次 |
+ | 重复1次或更多次 |
? | 重复0次或1次 |
{n} | 重复n次 |
{n,} | 重复n次或n次以上 |
{n,m} | 重复n次到m次 |
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>04量词</title>
</head>
<body>
<script>
//量词作用:用来确定某个模式出现的次数
// var reg = /^a$/;
// console.log(reg.test('a'));
// console.log(reg.test('aa'));
//1. * 相当于 >= 0 (可以出现0次或者是多次)
// var reg = /^a*$/;
// console.log(reg.test('a')); //true
// console.log(reg.test('aa')); //true
// console.log(reg.test('aaaaaa')); //true
// console.log(reg.test('')); //true
//2. + 相当于 >= 1 (可以出现1次或者是很多次)
// var reg = /^a+$/;
// console.log(reg.test('a')); //true
// console.log(reg.test('aa')); //true
// console.log(reg.test('aaaaaa')); //true
// console.log(reg.test('')); //false
//3. ? 相当于 0 || 1
//var reg = /^a?$/;
// console.log(reg.test('a')); //true
// console.log(reg.test('aa')); //false
// console.log(reg.test('aaaaaa')); //false
// console.log(reg.test('')); //true
//4. {n} 就表示重复n次
// var reg = /^a{3}$/; //必须重复3次
// console.log(reg.test('a')); //false
// console.log(reg.test('aa')); //false
// console.log(reg.test('aaa')); //true
// console.log(reg.test('aaaaaa')); //false
// console.log(reg.test('')); //false
//5. {n,} 相当于 >= n 表示重复次数是n次或更多次
// var reg = /^a{3,}$/; //必须重复3次或以上
// console.log(reg.test('a')); //false
// console.log(reg.test('aa')); //false
// console.log(reg.test('aaa')); //true
// console.log(reg.test('aaaaaa')); //true
// console.log(reg.test('')); //false
//6. {n,m} 表达式大于等于n,并且小于或等于m
var reg = /^a{3,6}$/; //必须重复6次到6次
console.log(reg.test('a')); //false
console.log(reg.test('aa')); //false
console.log(reg.test('aaa')); //true
console.log(reg.test('aaaaaa')); //true
console.log(reg.test('aaaaaaaaa')); //false
console.log(reg.test('')); //false
</script>
</body>
</html>
3.5 用户名校验
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>05用户户名校验</title>
<style>
span{
color: #aaa;
font-size: 14px;
}
.right {
color:green;
}
.wrong {
color:red;
}
</style>
</head>
<body>
<input type="text" class="username"><span>请输入用户名</span>
<script>
//正则表达式:只能是字母(大小写)数字或下划线,重复次数为6次到16次
var reg = /^[a-zA-Z0-9_]{6,16}$/;
//1.获取用户输入的用户名
var username = document.querySelector('.username');
var span = document.querySelector('span');
//输入完后,失去焦点(blur)触发事件
username.onblur = function(){
if(this.value == ''){
span.className = ''
span.innerHTML = '请输入用户名'
return false;
}
if(reg.test(this.value)){
span.className = 'right'
span.innerHTML = '用户名格式输入正确'
} else {
span.className = 'wrong'
span.innerHTML = '用户名格式输入错误'
}
}
</script>
</body>
</html>
3.6 括号总结
- 大括号:量词符,表示重复次数
- 中括号:字符集合,匹配方括号中的任意一个字符
- 小括号:表示优先级
工具大全[https://www.jyshare.com/]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
//小括号表示优先级
var reg = /^(abc){3}$/ // 表示abc重复3次
console.log(reg.test('abc'));
console.log(reg.test('abcabcabc'));
console.log(reg.test('abccc'));
</script>
</body>
</html>
3.7 预定义类
预定义类指的是某些常见的模式的简写方式
预定义类 | 说明 |
---|---|
\d | 匹配 0-9 之间的任意一个数字,相当于[0-9] |
\D | 匹配 0-9 之外的字符,相当于[^0-9] |
\w | 匹配任意的字母,数字和下划线,相当于[a-zA-Z0-9_] |
\W | 匹配除了任意的字母,数字和下划线,相当于[^a-zA-Z0-9_] |
\s | 匹配空格(包含了换行符、制表符、空格符等等)相当于[\t\r\n\v\f] |
\S | 除了匹配空格(包含了换行符、制表符、空格符等等)相当于[^\t\r\n\v\f] |
座机号校验
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
//小括号表示优先级
// var reg = /^(abc){3}$/ // 表示abc重复3次
// console.log(reg.test('abc'));
// console.log(reg.test('abcabcabc'));
// console.log(reg.test('abccc'));
//校验座机号:全国的做记号有两种格式:
//1)010-12345678
//2)0710-1234567
//var reg = /^[0-9]{3}-[0-9]{8}|[0-9]{4}-[0-9]{7}$/
//var reg = /^\d{3}-\d{8}|\d{4}-\d{7}$/
var reg = /^(\d{3}-\d{8})|(\d{4}-\d{7})$/
//var reg = /^\d{3,4}-\d{7,8}$/
console.log(reg.test('0710-8237789'));
console.log(reg.test('0710-12345678'));
console.log(reg.test('027-83891595'));
</script>
</body>
</html>
3.8.表单校验案例
window.onload = function(){
var tel = document.querySelector('#tel'); //手机号
var qq = document.querySelector('#qq'); //qq号
var nc = document.querySelector('#nc'); //昵称
var msg = document.querySelector('#msg'); //短信验证码
var pwd = document.querySelector('#pwd'); //登录密码
var surepwd = document.querySelector('#surepwd'); //确认密码
var regtel = /^1[3456789]\d{9}$/ //手机号正则表达式
var regqq = /^[1-9]\d{3,}$/ //qq正则表达式
var regnc = /^[\u4e00-\u9fa5]{2,8}$/ //昵称
var regmsg = /^\d{4}$/ //短信验证码
var regpwd = /^\w{6,11}$/ //密码
regex(tel,regtel); //手机号校验
regex(qq,regqq); //qq号校验
regex(nc,regnc); //昵称校验
regex(msg,regmsg); //验证码校验
regex(pwd,regpwd); //密码校验
// 表单校验函数
function regex(ele,reg){
ele.onblur = function(){
if(reg.test(this.value)){
this.nextElementSibling.className = 'success'
this.nextElementSibling.innerHTML = '<i class="success_icon"></i>恭喜您输入正确'
}else{
this.nextElementSibling.className = 'error'
this.nextElementSibling.innerHTML = '<i class="error_icon"></i>格式不正确,请重新输入'
}
}
}
surepwd.onblur = function(){
if(regpwd.test(pwd.value) == false){ //密码校验不通过
pwd.nextElementSibling.className = 'error'
pwd.nextElementSibling.innerHTML = '<i class="error_icon"></i>格式不正确,请重新输入'
pwd.focus();
return false;
}
if(this.value == pwd.value){
this.nextElementSibling.className = 'success'
this.nextElementSibling.innerHTML = '<i class="success_icon"></i>恭喜您输入正确'
}else{
this.nextElementSibling.className = 'error'
this.nextElementSibling.innerHTML = '<i class="error_icon"></i>格式不正确,请重新输入'
}
}
}
3.9 正则替换replace
replace方法可以实现替换字符串操作,用来替换的参数可以是一个字符串或者是一个正则表达式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>09replace</title>
</head>
<body>
<script>
// var str = 'pink和redpink';
// //replace对str这个字符串是没有做修改的
// var newStr = str.replace('pink','blue');
// console.log(newStr);
// //等同于此处的pin可以写在正则表达式里
// var newStr2 = str.replace(/pink/,'blue');
// console.log(newStr2);
//全部替换
var str = 'abcabc';
var newStr = str.replace(/a/g,'哈哈');
console.log(newStr);
//忽略大小写 i
var str2 = 'abcAbc';
var newStr2 = str.replace(/a/gi,'哈哈');
console.log(newStr2);
</script>
</body>
</html>
4.10 过滤敏感词汇
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>10过滤敏感词汇</title>
</head>
<body>
<textarea name="" id="message"></textarea><button>提交</button>
<div></div>
<script>
var btn = document.querySelector('button');
var message = document.querySelector('#message');
var div = document.querySelector('div');
btn.onclick = function(){
div.innerHTML = message.value.replace(/蔡徐坤|鸡哥/g,'**');
}
</script>
</body>
</html>
二、ES6入门
1.什么是ES6
ES的全称是:ECMAScript,它是ECMA国际标准化组织制定的一项脚本语言的标准规范
2015年6月:ES2015
2016年6月:ES2016
2017年6月:ES2017
2018年6月:ES2018
…
2.为什么要学习ES6
每一次标准的诞生都意味着语言的完善,功能的加强。javaScript语言本身也有一些不令人满意的地方。
- 变量提升特性增加了程序运行时的不可预测性。
- 语法过于松散,实现相同的功能,不同的人可能会写出不同的代码
3.ES6 新增的语法
3.1 let
es6中新增的用于声明变量的关键字.
let声明的变量只在所处的块级有效
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>11let</title>
</head>
<body>
<script>
//ES6中:如果一个变量用let声明,那么它只在所处的块级中有效
if(true){
let a = 10;
}
function fn(){
}
for(let i = 0; i <= 10; i++){
}
console.log(i);
console.log(a);
</script>
</body>
</html>
**注意:**使用let关键字声明的变量才具有块级作用域,使用var声明的变量不具备块级作用域特性
不存在变量提升
//不存在变量提升
console.log(a);
let a = 20;
暂时性死区
利用let声明变量会绑定这个块级作用域,不会受到外界的影响
var temp = 123;
if(true){
let temp;
temp = 'abc';
}
经典面试题
var arr = [];
for(var i = 0; i < 2; i++){
arr[i] = function(){
console.log(i);
}
}
arr[0]();
arr[1]();
关键是变量i是全局的,函数执行时候输出是全局作用域下的i的值
let arr = [];
for(let i = 0; i < 2; i++){
arr[i] = function(){
console.log(i);
}
}
arr[0]();
arr[1]();
关键点就在于每次循环都会产生一个块级作用域,每个块级作用于下的变量都是不同的,函数执行时输出的都是自己上一级(循环产生的块级作用域)下的i的值
小结
- let关键字就是用来声明变量的
- 使用let关键字声明的变量具有块级作用域
- 在一个大括号中使用let关键字声明的变量才具有块级作用域,var关键字声明的变量不具备块级作用域
- 防止循环变量变成全局变量,可以使用let声明变量
- 使用let官架子声明的变量没有变量提升
- 使用let关键字声明的变量具有暂时死区特性
3.2 const
声明常量,常量就是(内存地址)不能变化的量
具有块级作用域
if(true){
const a = 10;
}
console.log(a); //a is not defined
声明的时候必须赋值
const PI; //Missing initializer in const declaration
常量赋值后,值不能被修改
const PI = 3.14;
PI = 100; //Assignment to constant variable
小结
- const声明的变量是一个常量(值不能被修改)
- 既然是常量就不能重新再赋值,如果是基本数据类型,不能更改值。如果是复杂数据类型,不能更改地址值。
- 声明const的时候必须要给定值
3.3 let、const和var的区别
var | let | const |
---|---|---|
函数级作用域 | 块级作用域 | 块级作用域 |
变量提升 | 不存在变量提升 | 不存在变量提升 |
值可以修改 | 值可以修改 | 值不可更改 |
4.解构赋值
ES6中允许从数组中提取值,按照对一个位置,对变量赋值,对象也可以实现解构
4.1 数组解构
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>14数组解构</title>
</head>
<body>
<script>
let [a,b,c,d] = [1,2,3];
console.log(a);
console.log(b);
console.log(c);
console.log(d); //undefined
//如果解构不成功,变量的值就是undefined
</script>
</body>
</html>
4.2 对象解构
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>15.对象解构</title>
</head>
<body>
<script>
let person = {
name:'张三',
age:20,
gender:'男'
}
//对象解构 - 这种写法要求解构出来的变量名必须和属性名一致
let {name,age,gender} = person;
console.log(name);
console.log(age);
console.log(gender);
//对象解构 - 可以解构出来的变量名和属性名不一样 (myname,myage,sex都属于别名)
let {name:myname,age:myage,gender:sex} = person
console.log(myname);
console.log(myage);
console.log(sex);
</script>
</body>
</html>
小结
- 解构赋值就是把数据结构分解,然后给变量进行赋值
- 如果解构不成功,变量跟数值个数不匹配的时候,变量的值为undefined
- 数组解构用中括号包裹,对象解构用花括号包裹,多个变量之间用逗号分隔
- 利用解构赋值能够让我们方便的去取对昂中的属性和方法
小结
- 解构赋值就是把数据结构分解,然后给变量进行赋值
- 如果解构不成功,变量跟数值个数不匹配的时候,变量的值为undefined
- 数组解构用中括号包裹,对象解构用花括号包裹,多个变量之间用逗号分隔
- 利用解构赋值能够让我们方便的去取对昂中的属性和方法