【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();

 

posted @ 2019-08-20 16:42  ^finally  阅读(183)  评论(0)    收藏  举报