JavaScript 进阶学习
函数
函数定义
三种定义函数的方式:
使用
function
关键字 函数声明方式(命名函数):1
function fn(){};
函数表达式(匿名函数)
1
var fn = function(){};
调用
Function('参数1','参数2'..., '函数体')
构造函数:1
2var f = new Function('a', 'b', 'console.log(a + b)');
f(1, 2);
第三种方式执行效率低,也不方便书写,因此较少使用,但是要知道所有函数本质上都是 Function
的实例对象,可以通过函数对象的原型 __proto__
属性来获取到 Function
原型对象。
函数调用方式
1 |
|
函数中的 this
指向
调用函数的时候确定了 this
的指向,调用方式的不同决定了 this
的指向不同
一般来说 this
指向调用者,谁调用了函数 this
指向谁。.
JavaScript 提供了一些函数方法处理函数内部 this
的指向问题,常用的有 bind()
、call()
、apply()
三种方法。
call(thisArg, arg1, arg2, ...)
:执行这个函数对象,并且使函数运行时的this
指向thisArg
,arg1
,arg2
是向函数传递的其他参数,该方法的返回值就是函数对象执行得到的返回值。call()
常用于组合继承中子类调用父类的构造函数。1
2
3
4
5
6
7
8
9var o = {
name: 'andy'
}
function fn(a, b) {
console.log(this);
console.log(a+b)
};
fn(1,2)// 此时的this指向的是window
fn.call(o,1,2)//此时的this指向的是对象o,参数使用逗号隔开apply(thisArg, [argsArray])
:执行这个函数对象,并且使函数运行时的this
指向thisArg
,argsArray
是向函数传递的参数形成的数组。apply()
多用在数组相关的方法上,通过参数数组一次传入所有参数,不用再需要一个一个传参。1
2
3
4
5
6
7
8
9
10
11
12var o = {
name: 'andy'
}
function fn(a, b) {
console.log(this);
console.log(a+b);
};
fn() // 此时的 this 指向的是 window
fn.apply(o,[1,2]); // 此时的 this 指向的是对象 o,参数使用数组传递
var arr = [1, 2, 3];
Math.max.apply(null,arr); // 等效 Math.max(1,2,3);bind(thisArg, arg1, arg2, ...)
:该方法不会立刻执行函数对象,但是能改变将来函数运行时内部this
的指向,返回的是改变this
指向并传递完参数产生的新函数。bind()
多用于改变回调函数中this
的指向。
高阶函数
高阶函数就是对其他函数进行操作的函数,它接收函数作为参数或将函数作为返回值输出。
在 JavaScript 中,函数也是一种数据类型,函数对象可以作为参数传递给另外一个参数使用或者作为返回值传递回来。 最典型的就是一个函数对象作为参数传入,等待着被回调。
面向对象编程
在 JavaScript 中,对象是由属性和方法组成的,具体表现为一组无序键值对的集合。
在典型的 OOP 语言中(如 Java ),都存在类的概念,类就是对象的模板,对象就是类的实例,但在 ES6 标准之前,JavaScript 中并没用引入类的概念,对象不是基于类创建的,而是用一类称为构造函数的特殊函数来定义对象们的共同特征。
构造函数是一种特殊的函数,主要用来初始化对象,即为对象成员变量赋初始值,构造函数的调用与 new
一起使用。可以把对象中一些公共的属性和方法抽取出来,然使用 this
关键字封装到这个函数里面。
1 |
|
通常构造函数的首字母要大写,以和普通函数相区别,但这是一种约定,而不是强制规定。
实际上构造函数本质上和普通函数一样,都是 Function
对象实例,但是 this
和 new
让它的用法与普通函数有所区别。
使用 new
调用函数,那么这个函数就是构造函数,就是类模板,如果直接调用就是一个普通函数,其中的 this
指向全局对象。
使用 new
调用执行构造函数时会做四件事情:
- 在内存中创建一个新的空对象;
- 让构造函数中的
this
指向这个新的对象; - 执行构造函数里面的代码,给这个新对象添加属性和方法;
- 函数体执行完毕,返回这个新对象(所以构造函数里面不需要
return
关键字手动返回生成的对象)。
JavaScript 的构造函数中可以添加一些成员,可以在构造函数对象本身上添加,也可以在构造函数内部的 this
上添加。通过这两种方式添加的成员,就分别称为静态成员和实例成员。
- 静态成员:构造函数本身也是一个对象,所以可以为函数添加属性以及方法。在构造函数自身上添加的成员称为静态成员,也称为类成员,只能通过构造函数对象来访问,不能通过实例对象来访问,这一点和 Java 不一样。
- 实例成员:在构造函数内部使用
this
关键字创建的对象成员称为实例成员,只能由实例化的对象来访问。
1 |
|
原型对象 prototype
由于 JavaScript 中函数也是对象,每次使用构造函数实例化一个新对象时,实例方法也会被分配相应的内存,那么同样的方法在内存中存在多处副本,比较浪费内存。
JavaScript 规定,每个函数都有一个 prototype
属性,指向一个对象,也称为构造函数的原型对象。对于普通函数来说,该属性基本无用。但是,对于构造函数来说,生成实例的时候,该属性会自动成为实例对象的 __proto__
属性。
把实例方法直接定义在构造函数的 prototype
属性上,这样所有对象实例就可以共享同一个方法以节省内存,通过 prototype
原型对象添加的方法也叫原型方法。
1 |
|
通过原型对象,可以对 JavaScript 的内置对象添加自定义的方法。但不要给内置对象的原型对象整体赋值,这样原型对象原有的一些属性被覆盖或者丢失,只能为原型对象添加单个属性。比如给数组增加自定义求偶数和的功能:
1 |
|
对象原型 __proto__
实例对象都会有一个属性 __proto__
指向构造函数的 prototype
原型对象,之所以实例对象可以使用构造函数 prototype
原型对象的属性和方法,就是因为对象有 __proto__
原型的存在。
对象原型 __proto__
和原型对象 prototype
是等价的,指向的是同一个对象。
对象原型 __proto__
的意义就在于为对象的查找机制提供一个方向,或者说一条路线,但是它是一个非标准属性,因此实际开发中,避免使用该属性。
__proto__
并不是语言本身的特性,这是各大厂商具体实现时添加的私有属性,虽然目前很多现代浏览器的 JS 引擎中都提供了这个私有属性,但依旧不建议在生产中使用该属性,避免对环境产生依赖。生产环境中,我们可以使用Object.getPrototypeOf
方法来获取实例对象的原型,然后再来为原型添加方法/属性。
构造函数 constructor
对象原型 __proto__
和构造函数原型对象 prototype
里面都有一个 constructor
属性指回构造函数本身,也称之为构造函数属性。constructor
主要用于记录该对象引用于哪个构造函数,它可以让原型对象重新指向原来的构造函数。
一般情况下,对象的实例方法都在构造函数的原型对象 prototype
中设置。如果要通过原型对象一次添加多个实例方法,可以给原型对象采取对象形式赋值。但是这样赋值后,原型对象中原来的一些属性被覆盖或者丢失,其中 constructor
属性就不再指向当前构造函数了。因此应该在修改后的原型对象中,添加一个 constructor
属性指向原来的构造函数。
1 |
|
原型链
对象原型 __proto__
的意义就在于为对象成员查找机制提供一个方向,或者说一条路线。 每一个实例对象有一个 __proto__
属性,指向构造函数的原型对象 prototype
,构造函数的原型对象也是一个对象,也有 __proto__
属性指向原型对象的原型,这样一层一层就形成了原型链。
JavaScript 的原型链查找机制(规则):
- 当访问一个对象的属性(包括方法)时,首先查找这个对象自身有没有该属性。
- 如果没有就查找它的原型(也就是对象的
__proto__
属性指向的原型对象prototype
)有没有该属性。 - 如果还没有就查找原型对象的原型,依此类推一直找到 Object 的原型对象为止(Object 对象实例的
__proto__
属性值为null
)。
类的继承
大部分面向对象的编程语言,都是通过 extends
实现类的继承。在 ES6 之前,JavaScript 没有提供 extends
继承关键字,但可以通过构造函数和原型对象模拟实现继承,这种继承被称为组合继承。
借用构造函数继承父类属性的核心原理: 通过 call()
调用父类的构造函数,并把父类型的 this
指向子类型的 this
,这样就可以实现子类继承父类中的属性。
一般情况下,对象的方法都在构造函数的原型对象中设置,通过构造函数无法继承父类的原型方法,需要使用到原型对象。
借用原型对象继承父类方法的核心原理: 让子类的原型指向父类的原型,这样子类对象就可以通过原型链找到父类的方法,即继承了父类的方法。
组合继承步骤:
- 先定义父构造函数
- 再定义子构造函数
- 在子类的构造函数中通过
call()
调用父类的构造函数,并把父类型的this
指向子类型的this
,这样就可以实现子类继承父类中的属性。 - 让子类的原型对象
prototype
指向一个父类对象实例,这样子类就可以继承父类的方法。 - 将子类的
constructor
属性重新指向子类的构造函数。
1 |
|
让子类的原型对象 prototype
指向一个新创建的父类对象实例,子类对象可以通过 __proto__
属性接找到父类的对象原型 __proto__
中的方法。
ES5 新特性
Array
新增方法
下面的遍历数组的方法都接受一个函数作为参数,所有数组成员都会被依次传入该函数执行,其中 currentValue
是当前传入的数组成员的值,index
是传入成员项在数组中的索引,arr
是数组对象本身。
-
map(function(currentValue, index, arr))
:将数组的所有成员依次传入参数函数,然后把每一次的执行返回结果组成一个新数组返回。 -
forEach(function(currentValue, index, arr))
:forEach()
方法与map()
方法很相似,也是对数组的所有成员依次执行参数函数。但是,forEach()
方法不返回值,只用来操作数据,在函数里面return
也不会终止迭代。这就是说,如果数组遍历的目的是为了得到返回值,那么使用map()
方法,否则使用forEach()
方法。 -
filter(function(currentValue, index, arr))
:用于筛选数组用于过滤数组成员,它的参数是一个函数,所有数组成员依次执行该函数,函数返回为true
的成员组成一个新数组返回。该方法不会改变原数组。 -
some(function(currentValue, index, arr))
:用于检测数组中的是否存在元素满足指定条件,只要一个数组成员的执行该函数的返回值是true
,则整个some
方法的返回值就是true
,否则返回false
。 如果找到第一个满足条件的元素,则终止循环不在继续查找。 -
every(function(currentValue, index, arr))
:用于检测数组中的所有元素,所有成员传入函数执行的返回值都是true
,整个every
方法才返回true
,否则返回false
。
String
新增方法
-
trim()
:方法用于去除字符串两端的空格,返回一个新字符串,不改变原字符串。该方法去除的不仅是空格,还包括制表符(\t
、\v
)、换行符(\n
)和回车符(\r
)。
Object
方法
-
Object.keys(obj)
:获取到对象中的属性名,返回值是一个数组,该数组的成员都是该对象自身的(不包括继承的)所有属性名。返回的数组配合数组foeEach()
方法可以遍历原对象。 -
Object.defineProperty(obj, prop, descriptor)
:定义新属性或修改原有的属性,obj
是待修改的目标对象,prop
是需新增或修改的属性的名字,descriptor
描述对象用来说明目标属性所拥有的特性,描述对象有四个子属性,value
是要赋给目标属性的值。writable
决定目标属性值是否可以重写。如果该属性值为false
,则不允许再修改对象中的这个属性值。enumerable
决定目标属性是否可以被枚举遍历,如果值为false
则不允许遍历。configurable
决定目标属性是否可以被删除或是否可以再次修改特性,如果为false
则不允许使用delete
删除这个属性。
严格模式
ES5 提供了严格模式(strict mode)即在严格的条件下运行 JavaScript 代码。严格模式在 IE 10 以上版本的浏览器中才会被支持,旧版本浏览器中会被忽略。严格模式对正常的 JavaScript 语义做了一些更改:
- 消除了 Javascript 语法的一些不合理、不严谨之处,减少了一些怪异行为,例如未声明就使用变量。
- 消除代码运行的一些不安全之处,保证代码运行的安全。
- 提高编译器效率,增加运行速度。
- 禁用了在 ECMAScript 的未来版本中可能会重新定义的一些语法,为未来新版本的 Javascript 做好铺垫。比如一些保留字如:
class
、enum
、export
、extends
、import
、super
不能做变量名。
在正常模式中,如果一个变量没有声明就赋值,默认是全局变量。严格模式禁止这种用法,变量都必须先用声明,然后再使用,并且禁止使用 delete
删除已经声明变量。
严格模式中函数形参列表中不能有重名的参数,并且函数必须声明在顶层,不允许在非函数的代码块内声明函数。为了与新版本( ES6 中已引入)即将引入的块级作用域。
严格模式下 this
指向问题:
- 以前在全局作用域函数中的
this
指向全局对象(浏览器中是window
对象),严格模式下全局作用域中函数中的this
是undefined
。 - 以前构造函数时也可以当作普通函数不加
new
调用,其中this
指向全局对象。严格模式下,如果构造函数不加new
调用,由于this
指向的是undefined
构造函数汇中给this
添加属性的操作则会报错 - 其他类型函数中
this
和普通模式一样,new
调用构造函数中 this 指向创建的对象实例,定时器函数this
指向全局对象(浏览器中是window
对象),回调函数中this
指向调用者。
严格模式的更多要求请参考 MDN:严格模式。
严格模式可以应用到整个脚本或个别函数中。因此在使用时,我们可以将严格模式分为为脚本开启严格模式和为函数开启严格模式两种情况。
为脚本开启严格模式:在脚本的第一行,所有语句之前添加一行特定语句
"use strict";
或'use strict';
,老版本的浏览器会把该行它当作一行普通字符串表达式而忽略。1
2
3
4<script>
"use strict";
console.log("这是严格模式");
</script>为函数开启严格模式:把特定语句
"use strict";
或'use strict';
放在函数体所有语句之前,整个函数以 “严格模式” 运行。1
2
3
4function fn(){
"use strict";
console.log("这是严格模式");
}当有多个脚本文件需要合并时,可能其中有的脚本是严格模式,有的脚本是正常模式。可以将整个脚本文件中的代码放在一个立即执行的匿名函数之中,再在函数体所有语句之前添加严格模式声明,这样就不影响其他未开启严格模式的脚本文件。
1
2
3
4
5
6<script>
(function (){
"use strict";
console.log("这是严格模式");
})();
</script>
ES6 新特性
ES 的全称是 ECMAScript , 它是由 ECMA 国际标准化组织,制定的一项脚本语言的标准化规范。ES6 实际上是一个泛指,泛指 ES2015 及后续的版本。
let
关键字
let
是 ES6 中新增的用于声明变量的关键字,let
声明的变量只在所处于的块级有效。
使用 let 关键字声明的变量才具有块级作用域,使用var声明的变量不具备块级作用域特性。
1 |
|
使用 let
声明的变量不存在变量提升,必须先声明再使用,声明语句前访问会出现引用错误。
1 |
|
使用 let
声明的变量可能在代码块中存在一段临时性死区,全局作用域的同名变量也不能在死区之中访问。
1 |
|
const
关键字
const
关键字用来声明常量,const
和 let
一样,具有块级作用域。
1 |
|
由于 const
常量赋值后不可再更改,因此声明常量时就必须赋值,初始化常量。
1 |
|
常量就是值在第一次赋值初始化后不能再变化的量。具体来说,如果是基本数据类型,其存储的值不能更改,如果是复杂数据类型,由于其存储的是对象的引用地址,则不可再指向其他对象,但是对象中的值可以改变。
1 |
|
解构赋值
ES6 中允许在数组、对象中按照对应位置提取值,然后对变量赋值。如果变量跟数组元素个数或者对象属性个数不匹配的时候,则部分结构不成功,未匹配变量的值为 undefined
。
数组解构用中括号包裹,对象解构用花括号包裹,多个变量用逗号隔开。利用解构赋值能够很方便的提取对象中的属性跟方法。
数组解构赋值:
1 |
|
对象解构赋值:
1 |
|
箭头函数
箭头函数是 ES6 新增的定义匿名函数的方式,箭头函数表达式的语法比函数表达式更简洁。
小括号中是形参列表,大括号是函数体。
1 |
|
如果函数体中只有一句代码,且代码的执行结果就是返回值,可以省略大括号。
1 |
|
如果形参只有一个,可以省略小括号。
1 |
|
箭头函数不绑定 this
,arguments
,super
关键字,因此箭头函数只能作为普通函数不能作为类的构造函数使用。
箭头函数中的 this
,指向的是函数定义位置的上下文中的 this
。
1 |
|
使用箭头函数可以解决匿名函数 this
指向的问题,例如定时器中的回调函数中的 this
往往默认指向全局对象,此前只能手动更改其中 this
的指向或者使用额外的变量来传递 tihs
,现在可以直接使用箭头函数。
1 |
|
剩余参数
剩余参数语法允许将一些不定数量的参数表示为一个数组,这种方式很方便的去声明不知道参数情况下的一个函数,ES 6 之前要通过 arguments
对象来获取实参,比较麻烦。
1 |
|
剩余参数还可以和解构赋值一起使用:
1 |
|
模板字符串
模板字符串是 ES6 新增的创建字符串的方式,模板字符串使用反引号来代替普通字符串中的用双引号和单引号。
1 |
|
模板字符串中可以直接换行,不需要转义:
1 |
|
模板字符串中可以使用 ${ }
占位符嵌入表达式,表达式可以是一个简单的变量、运算操作、函数调用,
1 |
|
扩展运算符
扩展运算符可以将数组或者对象转为用逗号分隔的参数序列,又称为展开语法。
1 |
|
使用展开语法合并两个数组:
1 |
|
将伪数组或者可迭代对象转换为真正的数组:
1 |
|
Array
新增方法
Array.isArray()
:可以判断一个对象是不是真正的数组,真正的数组对象在生成对象的时候就必须是一个数组。将一个伪数组的__proto__
直接或间接指向Array.prototye
,就可以调用数组相关方法,但严格来说并不是一个真正的数组。obj instanceof Array
为ture
不能保证就是真正的数组。1
2
3
4
5
6
7
8
9
10
11
12// 定义一个伪数组对象
let arrayLike = {
'0': 'a',
'1': 'b',
'2': 'c',
length: 3
};
arrayLike.__proto__ = Array.prototype;
console.log(arrayLike instanceof Array); // true
console.log(Array.isArray(arrayLike)); // false
arrayLike.push(5);
console.log(arrayLike); // Array { '0': 'a', '1': 'b', '2': 'c', '3': 5, length: 4 }Array.from()
:将伪数组对象或可迭代对象转换为真正的数组,伪数组对象的属性名必须是对应的索引值,并且必须要有length
属性。将伪数组转换为真正数组之后就可以调用数组专属方法例如push()
、pop()
等。1
2
3
4
5
6
7
8
9
10
11
12
13// 定义一个伪数组对象
let arrayLike = {
'0': 'a',
1: 'b',
'3': 'd',
length: 5
};
let arr = Array.from(arrayLike); // 将伪数组转成数组
console.log(arrayLike instanceof Array); // false
console.log(Array.isArray(arrayLike)); // false
console.log(arr instanceof Array); // ture
console.log(Array.isArray(arr)); // true
console.log(arr); // [ 'a', 'b', undefined, 'd', undefined ]该方法还可以接受第二个参数,作用类似于数组的
map()
方法,用来对伪数组中每个元素进行处理,将处理后的值放入返回的数组。1
2
3
4
5
6let arrayLike = {
"0": 1,
"1": 2,
"length": 2
}
let newAry = Array.from(arrayLike, item => item *2) // [2,4]find()
:用于找出第一个符合条件的数组成员,如果没有找到返回undefined
。通过传入函数对象对数组元素进行遍历,如果找到第一个满足条件的元素,则终止循环不在继续查找,类似数组对象的some()
方法,区别是some()
返回布尔值,find()
返回查找到的元素。1
2
3
4
5
6
7
8let ary = [{
id: 1,
name: '张三'
}, {
id: 2,
name: '李四'
}];
let target = ary.find((item, index) => item.id == 2); // 找数组里面符合条件的值,当数组中元素id等于2的查找出来,注意,只会匹配第一个findIndex()
:用于找出第一个符合条件的数组成员的位置,如果没有找到返回 -1。1
2
3let ary = [1, 5, 10, 15];
let index = ary.findIndex((value, index) => value > 9);
console.log(index); // 2includes()
:表示某个数组是否包含给定的值,返回布尔值。1
2[1, 2, 3].includes(2) // true
[1, 2, 3].includes(4) // false
String 新增方法
startsWith(searchString[, position])
:用来判断当前字符串是否以另外一个给定的子字符串开头,返回布尔值。第一个参数是要搜索的子字符串。第二个参数搜索的开始位置,默认值为 0。1
2
3
4var str = "To be, or not to be, that is the question.";
alert(str.startsWith("To be")); // true
alert(str.startsWith("not to be")); // false
alert(str.startsWith("not to be", 10)); // trueendsWith(searchString[, length])
:用来判断当前字符串是否以另外一个给定的子字符串结尾,返回布尔值。第一个参数是要搜索的子字符串。第二个参数作为字符串的长度以判断字符串是否在结尾,默认值为被搜索字符串的长度。1
2
3
4var str = "To be, or not to be, that is the question.";
alert( str.endsWith("question.") ); // true
alert( str.endsWith("to be") ); // false
alert( str.endsWith("to be", 19) ); // truerepeat(n)
:方法表示将原字符串重复 n 次,返回一个新字符串。1
2console.log('x'.repeat(3)) // "xxx"
console.log('hello'.repeat(2)) // "hellohello"
Set
集合
ES6 提供了新的数据结构 Set
集合。它类似于数组,但是成员的值都是唯一的,没有重复的值。
使用 Set
构造函数用来生成 Set
对象:
1 |
|
Set()
构造函数可以接受一个数组作为参数,用来初始化集合,并且自动去掉数组汇总重复的元素:
1 |
|
-
add(value)
:在Set
对象尾部添加一个元素。返回该Set
对象。 -
delete(value)
:移除Set
中与这个值相等的元素,返回一个布尔值,表示删除是否成功。根据值相等删除而不是索引。 -
has(value)
:返回一个布尔值,表示该元素是否为 Set 对象的成员。 -
clear()
:清除所有成员,没有返回值。 -
forEach(callback[, thisArg])
:根据集合中元素的插入顺序,对所有元素依次执行提供的回调函数,用来遍历集合元素。
1 |
|
正则表达式
正则表达式(Regular Expression)是用于匹配字符串中字符组合的模式。
前端中的正则表达式主要用来:
- 对表单中用户输入的内容进行合法性验证;
- 提取大段文本中特定的字符串;
- 对文本内容的敏感内容进行查找替换。
在 JavaScript 中,正则表达式也是一种对象,可以通过两种方式创建一个正则表达式。
直接通过用斜杠
/
包裹起来的的字面量创建正则表达式:1
var re = /123/;
通过调用 RegExp 对象的构造函数创建:
1
2var rg = new RegExp(/123/);
var rg = new RegExp("123");
正则表达式对象的 test()
方法用来检测字符串是否符合该正则表达式规范,该方法会返回 true
或 false
,其参数是测试字符串,如果是其他类型会自动转换为字符串类型。
1 |
|
特殊字符
特殊字符也被称为元字符,在正则表达式中是具有特殊意义的专用符号,更多特殊字符请参考 MDN:正则表达式。
边界符(位置符):用来提示字符所处的位置,主要有两个字符:
^
:表示匹配行首的文本(以谁开始)$
:表示匹配行尾的文本(以谁结束)如果
^
和$
在一起使用,表示必须是精确匹配。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16var rg = /abc/; // 正则表达式里面不需要加引号 不管是数字型还是字符串型
// /abc/ 只要包含有abc这个字符串返回的都是true
console.log(rg.test('abc'));
console.log(rg.test('abcd'));
console.log(rg.test('aabcd'));
console.log('---------------------------');
var reg = /^abc/;
console.log(reg.test('abc')); // true
console.log(reg.test('abcd')); // true
console.log(reg.test('aabcd')); // false
console.log('---------------------------');
var reg1 = /^abc$/; // 精确匹配 要求必须是 abc字符串才符合规范
console.log(reg1.test('abc')); // true
console.log(reg1.test('abcd')); // false
console.log(reg1.test('aabcd')); // false
console.log(reg1.test('abcabc')); // false
[]
:字符组合,所有可供选择的字符都放在方括号内,包括方括号中的任意一个字符即匹配成功。方括号内部加上-
表示范围,例如,/[abcd]/
和/[a-d]/
是一样的,方括号内部头上的^
表示取反,只要包含方括号内的任一字符,都匹配失败。特殊符号在字符组合中没有特殊的意义,不需要再转义,/[a|b]/
相当于/a|\||b/
。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
26var rg = /[abc]/; // 只要包含有a 或者 包含有b 或者包含有c 都返回为true
console.log(rg.test('andy'));//true
console.log(rg.test('baby'));//true
console.log(rg.test('color'));//true
console.log(rg.test('red'));//false
var rg1 = /^[abc]$/; // 三选一 只有是a 或者是 b 或者是c 这三个字母才返回 true
console.log(rg1.test('aa'));//false
console.log(rg1.test('a'));//true
console.log(rg1.test('b'));//true
console.log(rg1.test('c'));//true
console.log(rg1.test('abc'));//true
var reg = /^[a-z]$/ //26个英文字母任何一个字母返回 true - 表示的是a 到z 的范围
console.log(reg.test('a'));//true
console.log(reg.test('z'));//true
console.log(reg.test('A'));//false
//字符组合
var reg1 = /^[a-zA-Z0-9]$/; // 26个英文字母(大写和小写都可以)任何一个字母返回 true
//取反 方括号内部加上 ^ 表示取反,只要包含方括号内的字符,都返回 false 。
var reg2 = /^[^a-zA-Z0-9]$/;
console.log(reg2.test('a'));//false
console.log(reg2.test('B'));//false
console.log(reg2.test(8));//false
console.log(reg2.test('!'));//true量词符:量词符用来设定某个模式出现的次数,
预定义类:预定义类指的是某些常见模式的简写方式。
()
:分组括号,提升了优先级,并且在之后可以提取括号内容所匹配的字符串。|
:选择符号,在几项之选择匹配一项,/[ab]/
等价于/a|b/
。/(a|b|c)/
和/[abc]/
在匹配效果上是等价的,但是前者中的小括号具有捕获引用功能,可以提取子匹配,而后者没有。/(?:a|b|c)/
和/[abc]/
则是完全等价,参考正则表达式中方括号和小括号的区别。
在正则表达式结尾可以通过修饰符来指定按照什么样的模式来匹配,常用的有以下三种修饰符组合:
- g:全局匹配
- i:忽略大小写
- gi:全局匹配 + 忽略大小写
1 |
|
正则表达式配合字符串的 replace(regexp/substr, replacement)
方法可以实现替换字符串操作,该方法传入的第一个参数可以是一个字符串或是一个正则表达式,第二个参数是要替代的字符串。
1 |
|
参考
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!