【JS基础】正则表达式--ES5--ES6--面向对象
正则表达式
应用对象:文本
使用正则表达式可以指定想要匹配的字符串规则,然后通过这个规则来匹配、查找、替换或切割那些符合指定规则的文本。
正则表达式的标识符: / /
PS:
" " 是 字符串str 的标识符、[ ] 是 数组arr 的标识符、{ } 是 对象obj 的标识符。
match 获取匹配的项目 返回数组
search 字符串搜索
replace 替换
正则表达式的创建
1.构造函数方式:
var reg=new RegExp("a");
2.字面量方式:
var reg=/a/;
正则方法
1.test 方法用于检测一个字符串是否匹配某个模式. 返回true和false;
2.exec( ) 找到了返回数组,找不到返回null;
量词
1.贪婪(贪心) 如 * 字符,贪婪量词会首先匹配整个字符串,尝试匹配时,它会选定尽可能多的内容,如果 失败则回退一个字符,然后再次尝试回退的过程就叫做回溯,它会每次回退一个字符,直到找到匹配的内容或者没有字符可以回退。相比下面两种贪婪量词对资源的消耗是最大的,
2.懒惰(勉强) 如 ? 字符,懒惰量词使用另一种方式匹配,它从目标的起始位置开始尝试匹配,每次检查一个字符,并寻找它要匹配的内容,如此循环直到字符结尾处。
3.占有 如 + 字符,占有量词会覆盖整个目标字符串,然后尝试寻找匹配内容 ,但它只尝试一次,不会回溯,就好比先抓一把石头,然后从石头中挑出黄金
---
1." * " 匹配 0个或多个, 相当于 {0, }
var str="aaaaaaaa"; var reg=/a*/; var res=reg.exec(str); console.log(res); 输出结果:"aaaaaaaa"
2." + " 匹配 1次或 更多(至少一个),相当于 {1, }
var str="aaabbsaassb"; var reg=/a+/; var res=reg.exec(str); console.log(res); 输出结果:"aaa"
3." ? " 匹配0个或者1个, 相当于{0, 1}
var str="aaabbsaassb"; var reg=/a?/; var res=reg.exec(str); console.log(res); 输出结果:"a"
4.{n}:匹配前一个字符正好出现n次
var str="aaabbsaassb"; var reg=/a{2}/; var res=reg.exec(str); console.log(res); 输出结果:"aa"
5.{n,}:匹配前一个字符出现n次以上,没有限制
var str="aaabbsaassb"; var reg=/a{2,}/; var res=reg.exec(str); console.log(res); 输出结果:"aaa"
6.{n,m}:匹配一个字符出现n到m次
var str = "aaaaaaaaabbsaassb"; var reg = /a{1,5}/; var res = reg.exec(str); console.log(res); 输出结果:"aaaaa"
元字符
【小写】
\d [0-9] 数字
\w [a-z0-9_] 数字,字母,下划线(之间没有空格)
\s 空白字符
\b 匹配单词边界
【大写】
\D 0-9 非数字
\W a-z0-9_ 非数字,字母,下划线
\S 非空白字符
. 表示任意字符
修饰符
i 忽略大小写
g 全局匹配
表达式
[abc] 查找方括号之间的任何字符 等同于 a|b|c
[0-9] 查找任何从 0 至 9 的数字
[a-z] 查找任何从小写 a 到小写 z 的字符
[A-Z] 查找任何从大写 A 到大写 Z 的字符
[A-z] 查找任何从大写 A 到小写 z 的字符
ES5
严格模式
进入严格模式 :"use strict"
1.针对整个脚本文件:将 "use strict" 放在脚本文件的第一行,则整个脚本文件都将以“严格模式”运行,
如果这行语句不在第一行,则无效,整个脚本以“正常模式”运行。
2.针对单个函数:将 "use strict" 放在函数的第一行,则整个函数以“严格模式”运行。
严格模式下的注意事项
1.全局变量声明时,必须加关键字(var)
正常模式:a = 10; console.log(a) //10
严格模式:a = 10; console.log(a) //a is not defined
2.this无法指向全局对象
正常模式:function fn(){ console.log(this) } //window
严格模式:function fn(){ console.log(this) } //undefined
3.函数内不允许出现重名参数
正常模式:function fn( a,b,b ){ console.log(a,b) }
fn(1,2,3) //1,3
严格模式:function fn( a,b,b ){ }
//报错:Duplicate parameter name not allowed in this context 在此上下文中不允许出现重复的参数名
4.arguments对象
4.1 arguments对象不允许被动态改变
正常模式:
function fn(a){ a=20; console.log(a); //20 console.log(arguments[0]); //20 } fn(10);
严格模式:
function fn(a){ a=20; console.log(a); //20 console.log(arguments[0]); //10 } fn(10);
5、不允许使用arguments.callee
6.新增的保留字:implements,interface,let,package,private,protected,public,static,yield
ES5新增数组方法:
索引方法:indexOf() 和 lastIndexOf();
1、indexOf(data,start):接收两个参数:参数1表示 要查找的数组元素 参数2表示要从什么位置开始查找。(从左到右)
2、lastIndexOf() (从右到左)
迭代方法:forEach()、map()、filter()、some()、every();
1、forEach(): 循环对数组进行遍历循环,对数组中的每一项运行给定函数。这个方法没有返回值 2、map(callback): 会遍历当前数组,然后调用参数中的方法,返回当前方法的返回值 3、filter() :遍历和过滤 4、some(): 方法用于检测数组中的元素是否满足指定条件(函数提供)。如果有一个元素满足条件,则表达式返回true , 剩余的元素不会再执行检测。否则返回false 5、every(): 用于检测数组所有元素是否都符合指定条件(通过函数提供)。如果有一个不符合就返回false
归并方法:reduce()、reduceRight();
1、reduce() 方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值。
//参数1表示 数组第一项元素 参数2表示数组剩余的元素 参数3表示数组剩余的下标 2、reduceRight() 方法的功能和 reduce() 功能是一样的,不同的是 reduceRight() 从数组的末尾向前将数组中的数组项做累加。
//参数1表示 数组最后一项元素 参数2表示数组剩余的元素 参数3表示数组剩余的下标
字符串方法
trim( ) 去掉字符串前后空格;
trimLeft( ) 去掉字符串前面空格
trimRight( ) 去掉字符串后面空格
反序列化
JSON.parse(str); 字符串---->>json 用于从一个字符串中解析出json对象 var str = '{"name" : "张三", "sex" : "男"}'; console.log(JSON.parse(str));//{name: "张三", sex: "男"} typeof object 注意点:单引号写在{}外,每个属性名都必须用双引号,否则会抛出异常。
序列化
JSON.stringify(); obj(json)------>>字符串 用于从一个对象解析出字符串 var obj={ name:"张三", sex:"男", } console.log(JSON.stringify(obj))//{"name":"张三","sex":"男"} typeof string
日期对象得到当前日期的毫秒数
Date.now(); before: var d = new Date(); var res = d.getTime(); now: var s = Date.now();
ES6
ES6新增定义变量的方法
1.let
let定义的变量没有声明提升,在 { } 中有let定义变量,该区域就会变成块级作用域。 { let b =10; console.log(b) //输出10 } console.log(b) // a is not defined PS:在一个大括号中用let声明的变量在外部不可访问了,每个大括号都是独立的作用域!!!
Before:
for(var i = 0 ; i < aLi.length ; i ++){ //事件在循环里面,先执行循环,循环彻底结束后再执行事件。
aLi[i].onclick = function(){
//console.log(i) 这是输出的i永远都是aLi.length
this.style.color="red";
}
}
Now:
for(let i = 0 ; i < aLi.length ; i ++){ //执行一次循环,就执行一次事件。
aLi[i].onclick = function(){
aLi[i].style.color="red";
}
}
有了let声明我们在函数外部就无法访问到 i ,i作为下标只存在于for循环中, 所以,这个时候每个i都是独立的;我们在点击的时候可以轻易的获取当前元素的下标.
关于暂时性死区:
var a = 10; if(true){ console.log(a);//ReferenceError(引用错误): a is not defined; let a = 20; } PS:ES6规定在某个区块中, 一旦用let或const声明一个变量,那么这个区块就变成块级作用域,用let 或者const声明的变量即为该区块绑定,
该变量不受任何变量影响。 在该变量使用let声明前不可以用。在语法上,我们叫这种情况为:暂时性死区 (temporal dead zone,简称 TDZ)
2.const
常量(不能改变的量),赋值和覆盖都不可以改变它的值。同样在 { } 中有const定义变量,该区域就会变成块级作用域。
const a =20;
a=30;
console.log(a); //报错 不能重新赋值
知识了解
Unicode编码
ES6字符串扩展
1.字符串新增方法
repeat()
var str="我永远拥护中国"
var res=str.repeat(10); //复制str字串符10遍
console.log(res)
includes() startsWith() endsWith() 判定字符串中是否存在某个字符串
var s = 'Hello world!';
s.startsWith('Hello') // true 以参数开头
s.endsWith('!') // true 以参数结尾
s.includes('o') // true 包括参数;
第二种方法接受第二个参数,第二个参数表示从第几位开始;
var s = 'Hello world!';
s.startsWith('world', 6) // true
s.endsWith('Hello', 5) // true
s.includes('Hello', 6) // false
for of
可以用于遍历字符串:
var str= "abcd";
for(var i of str){
console.log(i) //输出a b c d
}
字符串模板
ES6中存在一种新的字符串, 这种字符串是 以 `` (波浪线上的那个字符 > 反引号)括起来表示的;
拼接
befor:
变量+"<p>"+变量+"</p>"+变量
now:
`${变量}<p>${变量}</p>${变量}`
输出一个表格:
var str = `
<table>
<tr>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
</table>
`
document.write(str);
箭头函数
var obj = { left : 200, move : function(){ setTimeout( ()=>{ this.left = 100; },1000); } }
PS:箭头函数this指向的固定化,并不是因为箭头函数内部有绑定this的机制,实际原因是箭头函数根本没有自己的this,导致内部的this就是外层代码块的this。正是因为这个,所以箭头函数也不能做构造函数。
解构赋值
基本
var [a,b,c] = [1,2,3];
// a = 1
// b = 2
// c = 3
可嵌套
let [a, [[b], c]] = [1, [[2], 3]];
// a = 1
// b = 2
// c = 3
可忽略
let [a, , b] = [1, 2, 3];
// a = 1
// b = 3
不完全解构
let [a = 1, b] = [];
// a = 1, b = undefined
字符串等
let [a, b, c, d, e] = 'hello';
// a = 'h'
// b = 'e'
// c = 'l'
// d = 'l'
// e = 'o'
应用:交换两个变量的值
before:
var a=10;
var b=20;
var temp;
temp = a;
a = b;
b = temp;
now:
var a = 10;
var b = 20;
console.log(a, b);
[b, a] = [10, 20];
console.log(a, b);
ES6新增的基本数据类型
symbol :凡是属性名属于 Symbol 类型,就都是独一无二的,可以保证不会与其他属性名产生冲突
var sy1=sybol("10");
var sy2=sybol("10");
console.log(sy1==sy2); //false
ES6新数据结构set
类似数组,但是成员的值都是唯一的,没有重复性(可用于去重)
属性
size:返回值得长度
var s=new Set(["a","b","c","d"])
console.log(s.size) //输出 4
方法
add(value) 添加一个值,返回Set结构本身
var s=new Set(["a","b","c","d"])
var res= s.add("我是新增的")
console.log(res) //输出 {"a", "b", "c", "d", "我是新增的"}
delete(value) 删除某个值,返回布尔值
var s=new Set(["a","b","c","d"])
var res= s.delete("d")
console.log(s) //输出 {"a", "b", "c"}
console.log(res) //输出 true
has(value) 返回布尔值,表示是否是成员
var s=new Set(["a","b","c","d"])
var res= s.has("d")
console.log(s) //输出 {"a", "b", "c","d"}
console.log(res) //输出 true
clear() 清除所有成员,无返回值
var s=new Set(["a","b","c","d"])
var res= s.clear()
console.log(s) //输出 Set(0) {}
面向对象
面向对象(Object Oriented,OO)是软件开发方法,一种高级的编程思想。
面向对象的特点
封装
不考虑内部实现,只考虑功能实现(全局变量会导致命名污染问题)。
继承
从已有对象上,继承出新对象(获取已存在的对象已有的属性和方法的)。
//简单的继承
var obj1 = {name : "张三", age : 18}; var obj2 = {}; for(var i in obj1){ obj2[i] = obj1[i]; } console.log(obj2);
多态
多态, 统一操作结果会不一样
var arr = ["a", "c", "d"]; var res = arr.toString(); console.log(res); console.log(typeof res); var obj = { name : "张三", age : 18 } var res2 = obj.toString(); console.log(res2); console.log(typeof res2);
类与对象的关系
JavaScript中的类相当于图纸,用来描述一类事物。
JavaScript中可以自定义类, 但是也提供了一个默认的类叫做Object。
function Person(name, age){ //这就是 类 相当于模板 this.name = name; this.age = age; this.say = function(){ console.log("hello"); } } var p1 = new Person("小明", 18); //实例化,通过类实例化出来的对象 var p2 = new Person("熊大", 20); console.log(p1, p2);
创建对象的方式
1.通过new Object( )创建对象
var obj = new Object(); //创建一个空对象 obj.name = "李长波"; //设置属性 obj.age = 24; obj.sex = "男"; obj.say = function () { //设置方法 console.log("我是李长波"); } console.log(obj.name); //使用属性 obj.say(); //使用方法
2.通过字面量创建对象
var obj = { name: "李长波", //设置属性 age: 24, sex: "男", say: function () { //设置方法 console.log("我是李长波"); } } console.log(obj.name); //使用属性 obj.say(); //使用方法
3.通过工厂函数创建对象
第一种形式
function person(name,age,sex){ var obj=new Object(); //创建一个空对象 obj.name=name; //设置属性 obj.age=age; obj.sex=sex; obj.say=function(){ //设置方法 console.log("我是工厂函数的第一种形式创建的"); } return obj; //把对象返回给外界 } var p1=person("李长波",24,"男"); console.log(p1);
第二种形式
function person(name,age,sex){ var obj={ name:name, age:age, sex:sex, say:function(){ console.log("我是工厂函数的第二种形式创建的"); } } return obj; } var p1=person("李长波",24,"男"); console.log(p1);
函数中的this关键字
每个函数中都有一个this,根据调用方式不同,this的指向就不同。谁调用当前函数,this就是谁。
1.默认情况下直接调用的函数都是由window调用的:
function fn(){ console.log(this);//window } fn();
2.如果函数作为对象的方法,由对象来调用函数,这个时候函数里面的this就是对象本身。
var obj = { name : "张三", age : 18, say : function(){ console.log(this); //指的是obj对象本身 } } obj.say();
构造函数
1、什么是构造函数?构造函数和工厂函数是一样的,都是专门用来创建对象的,构造函数本质上来说是工厂函数的简写。
2、构造函数和工厂函数的区别?
①构造函数的函数名称必须首字母大写;
②构造函数只能通过new关键字来调用。
function Person(name, age){ this.name = name; this.age = age; this.say = function(){ console.log("hello"); } } var p1 = new Person("小明", 18); var p2 = new Person("小花", 20); console.log(p1, p2);
对比上面的工厂形式,系统为我们做了什么?
会在构造函数中自动创建一个对象,将自动创建的对象赋值给this,会在构造函数的最后自动添加return this;
function Person(name, age, sex) { //var obj=new Object(); //系统自动添加 //this=obj; //系统自动添加 this.name = name; this.age = age; this.sex = sex; this.say = function () { console.log("我是李长波"); } //return this; //系统自动添加 } var p1 = new Person("李长波", 24, "男"); console.log(p1); p1.say();

浙公网安备 33010602011771号