Object
对象是JS中的引用数据类型
对象是一种复合数据类型,在对象中可以保存多个不同数据类型的属性
使用typeof检查一个对象时,会返回object
对象的分类
-
内建对象:由ES标准中定义的对象,在任何的ES的实现中都可以使用,比如:Math、String、Number、Boolean、Function、Object ...
-
宿主对象:由JS的运行环境提供的对象,目前来讲主要指由浏览器提供的对象,比如 BOM DOM。如:console、document
-
自定义对象:由开发人员自己创建的对象。
创建对象
- 方式一:
- var obj = new Object();
- 方式二:使用对象字面量{},更简洁
- var obj = {};
向对象中添加属性
-
语法:
对象.属性名 = 属性值;
对象["属性名"] = 属性值;
-
属性名没有任何要求,不需要遵守标识符的规范,但是在开发中,尽量按照标识符的要求去写。
-
属性值也可以任意的数据类型,甚至也可以是一个对象。
读取对象中的属性
- 语法:
-
对象.属性名
-
对象["属性名"]—属性名特殊时
obj["nihao"]="你好"
-
- 如果读取一个对象中没有的属性,它不会报错,而是返回一个undefined
删除对象中的属性
-
语法:
delete 对象.属性名
delete 对象["属性名"]
使用in检查对象中是否含有指定属性
- 语法:"属性名" in 对象
- 如果在对象中含有该属性,则返回true,如果没有则返回false
使用对象字面量,在创建对象时直接向对象中添加属性
语法:
var obj = {
属性名:属性值,
属性名:属性值,
属性名:属性值,
属性名:属性值
}
基本数据类型和引用数据类型
-
基本数据类型
String Number Boolean Null Undefined
-
引用数据类型
Object
-
基本数据类型的数据,变量是直接保存的它的值,保存在栈。
变量与变量之间是互相独立的,修改一个变量不会影响其他的变量。
-
引用数据类型的数据,变量是保存的对象的引用(内存地址)(引用存在栈中),保存在堆。
如果多个变量指向的是同一个对象,此时修改一个变量的属性,会影响其他的变量。
-
比较两个变量时,对于基本数据类型,比较的就是值,
对于引用数据类型比较的是地址,地址相同才相同
函数(Function)
- 函数也是一个对象,也具有普通对象的功能
- 函数中可以封装一些代码,在需要的时候可以去调用函数来执行这些代码
- 使用typeof检查一个函数时会返回function
创建函数
-
字符串封装代码创建函数
-
函数声明
function 函数名([形参1,形参2...形参N]){ 语句... } //与构造函数方式一样,函数声明的方式更清楚。声明函数,末尾不用写“;”。
-
函数表达式
var 函数名 = function([形参1,形参2...形参N]){ 语句... }; //创建一个匿名函数,将此匿名函数赋值给一个变量(赋值语句,最好在末尾写“;”)。
调用函数
-
语法:函数对象([实参1,实参2...实参N]);
fun() sum() alert() Number() parseInt()
-
当我们调用函数时,函数中封装的代码会按照编写的顺序执行
形参和实参
JS中的所有的参数传递都是按值传递的
- 形参:形式参数
-
定义函数时,可以在()中定义一个或多个形参,形参之间使用,隔开
定义形参就相当于在函数内声明了对应的变量但是并不赋值,形参会在调用时才赋值。
-
- 实参:实际参数
-
调用函数时,可以在()传递实参,传递的实参会赋值给对应的形参,
调用函数时JS解析器不会检查实参的类型和个数,可以传递任意数据类型的值。
如果实参的数量大于形参,多余实参将不会赋值,
如果实参的数量小于形参,则没有对应实参的形参将会赋值undefined
-
实参可以传递任意类型的数据,包括对象和函数
-
返回值
-
使用return 来设置函数的返回值,即函数执行的结果
-
语法:return 值;
- 该值就会成为函数的返回值,可以通过一个变量来接收返回值
-
return后边的代码都不会执行,一旦执行到return语句时,函数将会立刻退出。
-
如果return后不跟值,或者是不写return则函数默认返回undefined。
-
return后可以跟任意类型的值,可以是基本数据类型,也可以是一个对象或函数。
undefined是因为alert无返回值,即fun4无返回值
fun():返回的是这个函数的返回值,fun:返回的是这个函数, a=fun3(),即a=fun4。a(),即fun4()。fun3()()即fun3()()=a()=fun4()='我是fun4'
-
-
break、continue和return
- break
- 退出循环
- continue
- 跳过当次循环
- return
- 退出函数
- break
-
alert无返回值
立即执行函数
立即执行函数:函数定义完,立即被调用,这种函数叫做立即执行函数,立即执行函数往往只会执行一次。
闭包
闭包是JS一个非常重要的特性,这意味着当前作用域总是能够访问外部作用域中的变量。因为函数是JS中唯一拥有自身作用域的结构,因此闭包的创建依赖于函数。也可以将闭包的特征理解为,其相关的局部变量在函数调用结束之后将会继续存在。
函数作为对象的方法
-
将函数作为对象的属性保存
-
可以将一个函数设置为一个对象的属性,当一个对象的属性是一个函数时,我们称这个函数是该对象的方法。
-
对象.方法名();
-
函数名();
-
-
枚举对象中的属性【使用for ... in 语句】
函数作为参数
函数和其他对象一样,也可以作为一个参数传递给另外一个函数。
但是要注意的是使用函数作为参数时,变量后边千万不要加(),不加()表示将函数本身作为参数,加上以后表示将函数执行的结果作为参数
函数方法
call()
apply()
-
这两个方法都是函数对象的方法需要通过函数对象来调用
-
通过两个方法可以直接调用函数,并且可以通过第一个实参来指定函数中this
- 第一个实参是谁,this代表谁。无第一个实参则this代表window
-
不同的是call是直接传递函数的实参,而apply需要将实参封装到一个数组中传递
obj.fun(); //报错,因为obj中没有fun方法
fun.call(obj); //不报错,利用call实现obj去调用fun
函数内部属性
this
-
我们每次调用函数时,解析器都会将一个上下文对象作为隐含的参数传递进函数。
使用this来引用上下文对象,根据函数的调用形式不同,this的值也不同。
-
this的不同的情况:
1.以函数的形式调用时,this是window
2.以方法的形式调用时,this就是调用方法的对象
3.以构造函数的形式调用时,this就是新创建的对象
4.使用call和apply调用时,this是指定的那个对象
5.在全局作用域中this代表window
arguments
在调用函数时,浏览器每次都会传递进两个隐含的参数:
- 函数的上下文对象 this
- 封装实参的对象 arguments
-
该对象实际上是一个数组,用于保存函数的实参。
-
arguments.length可以用来获取实参的长度
-
我们即使不定义形参,也可以通过arguments来使用实参,只不过比较麻烦
- arguments[0] 表示第一个实参
- arguments[1] 表示第二个实参
-
它里边有一个属性叫做callee,表示当前函数
-
作用域
作用域简单来说就是一个变量的作用范围。
全局作用域
- 直接在script标签中编写的代码都运行在全局作用域中
- 全局作用域在打开页面时创建,在页面关闭时销毁。
- 全局作用域中有一个全局对象window,window对象由浏览器提供,可以在页面中直接使用,它代表的是整个的浏览器的窗口。
- 在全局作用域中创建的变量都会作为window对象的属性保存,在全局作用域中创建的函数都会作为window对象的方法保存
- 在全局作用域中创建的变量和函数可以在页面的任意位置访问。在函数作用域中也可以访问到全局作用域的变量。
- 尽量不要在全局中创建变量
函数作用域
- 每调用一次函数就会创建一个新的函数作用域,他们之间是互相独立的。
- 函数作用域在函数执行时创建,在函数执行结束时销毁。
- 在函数作用域中可以访问到全局作用域的变量,在全局作用域中无法访问到函数作用域的变量。
- 当在函数作用域操作一个变量时,它会先在自身作用域中寻找,如果有就直接使用;如果没有则向上一级作用域中寻找,直到找到全局作用域;如果全局作用域中依然没有找到,则会报错ReferenceError。
- 在函数中要访问全局变量可以使用window对象。
变量的声明提前
-
在全局作用域中,
-
使用var关键字声明的变量会声明提前,但是不会赋值。所以我们可以在变量声明前使用变量
-
不使用var关键字声明的变量不会被声明提前。
-
-
在函数作用域中,
-
使用var关键字声明的变量会声明提前
-
不使用var关键字声明变量,则变量会变成全局变量
-
定义形参就相当于在函数作用域中声明了变量(相当于fun6中定义了一个var e;)
-
函数的声明提前
-
在全局作用域中,
- 使用函数声明创建的函数(function fun(){}),会声明提前,即可以在函数声明前去调用函数
- 使用函数表达式(var fun = function(){})创建的函数没有该特性
函数声明创建的函数,声名提前。函数表达式创建的函数,声明不会提前
-
在函数作用域中,
-
使用函数声明创建的函数,会声明提前。
-
局部变量/全局变量【小练习】
构造函数
构造函数是专门用来创建对象的函数
概念
构造函数定义
- 一个构造函数我们也可以称为一个类
- 通过一个构造函数创建的对象,我们称该对象为这个构造函数的实例
- 通过同一个构造函数创建的对象,我们称为一类对象
构造函数与普通函数
-
构造函数就是一个普通的函数,创建方式和普通函数没有区别。
-
任何函数都可以通过new来调用,所以函数都可以是构造函数。构造函数的首字母大写,用于区分普通执行函数。
-
构造函数和普通函数的区别就是:调用方式的不同;
- 普通函数是直接调用
- 构造函数需要使用new关键字来调用。
构造函数的执行流程
1.创建一个新的对象
2.将新的对象作为函数的上下文对象(this)
3.执行函数中的代码
4.将新建的对象返回
instanceof
- 用来检查一个对象是否是一个类的实例
- 任何对象使用typeof都会返回Object,无法获取对象的具体类型
- 语法:对象 instanceof 构造函数
-
如果该对象时构造函数的实例,则返回true,否则返回false
-
Object是所有对象的祖先,所以任何对象和Object做instanceof都会返回true
-
for...in
-
枚举对象中的属性
-
语法:
for(var 属性名 in 对象){ }
for...in语句的循环体会执行多次,对象中有几个属性就会执行几次,
每次讲一个属性名赋值给我们定义的变量,我们可以通过它来获取对象中的属性:对象名[属性名]
使用工厂方法创建对象【大批量的创建对象】
使用工厂方法创建的对象,使用的构造函数都是Object,所以创建的对象都是Object这个类型,就导致我们无法区分出多种不同类型的对象。
使用构造函数创建对象
构造函数是new 你自己定义的函数(),返回的名称也就是你自己定义的。
优化
创建一个Person构造函数。在Person构造函数中,为每一个对象都添加了一个sayName方法。
目前我们的方法是在构造函数内部创建的,也就是构造函数每执行一次就会创建一个新的sayName方法,也是所有实例的sayName都是唯一的。
这样就导致了构造函数执行一次就会创建一个新的方法,执行10000次就会创建10000个新的方法,而10000个方法都是一摸一样的。
这是完全没有必要,完全可以使所有的对象共享同一个方法。
但是:
如果写在Person对象里面,每次new Person,都会创建sayName方法对象,浪费内存。但是如果放在外面,sayName()就属于Window对象,调所有对象里的sayName都是调用的外部Window对象中的sayName。
- 好处:易维护,如果两个构造函数拥有同一个函数功能就可以单独拿出来写,不用每次修改功能都每个地方改一下。
- 坏处:将函数定义在全局作用域,污染了全局作用域的命名空间,而且定义在全局作用域中也很不安全。
原型(prototype)
prototype属性只存在于函数对象中,其他对象是没有prototype属性的。
概念
-
创建一个函数以后,解析器都会默认在函数中添加一个数prototype,prototype指向原型对象。
原型就是一个对象,和其他对象没有任何区别
-
当函数作为构造函数使用,它所创建的对象中都会有一个隐含的属性执行该原型对象。
隐含的属性:通过 对象.__proto__来访问。
-
原型对象就相当于一个公共的区域,凡是通过同一个构造函数创建的对象他们通常都可以访问到相同的原型对象。
我们可以将对象中共有的属性和方法统一添加到原型对象中,这样我们只需要添加一次,就可以使所有的对象都可以使用。
获取原型对象
– 构造函数. prototype
– Object.getPrototypeOf(对象)
– 对象.proto
– 对象. constructor.prototype
我们可以获取到Object的原型对象,也可以对它的属性进行操作,但是我们不能修改Object原型对象的引用。
向原型中添加属性
当我们使用一个对象的属性或方法时,会现在自身中寻找,
-
自身中如果有,则直接使用,
-
如果没有则去原型对象中寻找,如果原型对象中有,则使用,
-
如果没有则去原型的原型中寻找,直到找到Object对象的原型,
-
Object对象的原型没有原型(为null),如果在Object原型中依然没有找到,则返回undefined。
向原型中添加方法
-
以后我们创建构造函数时,可以将这些对象共有的属性和方法,统一添加到构造函数的原型对象中。
这样不用分别为每一个对象添加共有的属性和方法,也不会影响到全局作用域,就可以使每个对象都具有这些属性和方法了。
-
检查对象中是否含有某个属性
-
使用in:原型含有也返回true
-
使用hasOwnProperty:只有自身含有才返回true
-
toString()
-
当我们直接在页面中打印一个对象时,实际上是输出的对象的toString()方法的返回值。
toString()方法属于Object原型的方法
-
如果我们希望在输出对象时不输出“[object Object]”
-
可以为对象添加一个toString()方法。覆盖Object中的toString()
但是此方法需要在每个对象都添加toString()方法
-
在原型上添加toString()方法
-
垃圾回收
当一个对象没有任何的变量或属性对它进行引用,此时我们将永远无法操作该对象,此时这种对象就是一个垃圾,这种对象过多会占用大量的内存空间,导致程序运行变慢,所以这种垃圾必须进行清理。
在JS中拥有自动的垃圾回收机制,会自动将这些垃圾对象从内存中销毁,我们不需要也不能进行垃圾回收的操作,我们需要做的只是要将不再使用的对象设置null即可。
数组(Array)
- 数组也是一个对象。
- 它和我们普通对象功能类似,也是用来存储一些值的。
- 不同的是普通对象是使用字符串作为属性名的,而数组是使用数字来作为索引操作元素。
- 索引:从0开始的整数就是索引。
- 数组的存储性能比普通对象要好,在开发中我们经常使用数组来存储一些数据。
数组的操作
创建数组
-
使用构造函数创建 var arr = new Array();
-
使用“字面量”创建 var arr = [];
向数组中添加元素
-
语法:数组对象[索引] = 值;
创建数组时直接添加元素
- 语法:var arr = [元素1,元素2....元素N];
-
例子:
var arr = [123,"hello",true,null];
-
查找数组元素
- 语法:数组对象[索引]
- 如果读取不存在的索引,不会报错,会返回undefined
获取数组的长度
- 使用length属性来操作数组的长度
- 语法:数组.length
- 对于连续的数组,使用length可以获取到数组的长度(元素的个数)。
- 对于非连续的数组,使用length会获取到数组的最大的索引+1,尽量别创建非连续数组
修改数组的长度
- 语法:数组.length = 新长度
- 如果修改后的length大于原长度,则多出的部分会空出来
- 如果修改后的length小于原长度,则原数组中多出的元素会被删除
向数组的最后添加元素
- 语法:数组[数组.length] = 值;
数组中的元素可以是任意的数据类型
数组的方法
- push()
-
用来向数组的末尾添加一个或多个元素,并返回数组新的长度
-
语法:数组.push(元素1,元素2,元素N)
-
- pop()
-
用来删除数组的最后一个元素,并返回被删除的元素
-
- unshift()
-
向数组的前边添加一个或多个元素,并返回数组的新的长度
-
向前边插入元素以后,其他的元素索引会依次调整。
-
- shift()
-
删除数组的前边的一个元素,并返回被删除的元素
-
- slice()
-
可以从一个数组中截取指定的元素
-
该方法不会影响原数组,而是将截取到的内容封装为一个新的数组并返回(
-
参数:
1.截取开始位置的索引(包括开始位置)
2.截取结束位置的索引(不包括结束位置) - 第二个参数可以省略不写,如果不写则一直截取到最后 - 参数可以传递一个负值,如果是负值,则从后往前数 - -1 倒数第一个
- -2 倒数第二个
-
- splice()
-
可以用来删除数组中指定元素,并使用新的元素替换
该方法会将删除的元素封装到新数组中返回(返回删除的元素)
删除后,后面元素会自动补位
-
参数:
1.删除开始位置的索引
2.删除的个数
3.三个以后,都是替换的元素,这些元素将会插入到开始位置索引的前边
-
- reverse()
-
可以用来反转一个数组,它会对原数组产生影响
-
- concat()
-
可以连接两个或多个数组,它不会影响原数组,而是新数组作为返回值返回
-
- join()
-
可以将一个数组转换为一个字符串,
-
该方法不会对原数组产生影响,而是将转换后的字符串作为结果返回。
-
参数:
需要一个字符串作为参数,这个字符串将会作为连接符来连接数组中的元素
如果不指定连接符则默认使用,
-
- sort()
-
可以对一个数组中的内容进行排序,默认按照Unicode编码进行排序(数字也是)
调用以后,会直接修改原数组。
-
可以自己指定排序的规则,需要一个回调函数作为参数:
回调函数中需要定义两个形参,使用哪个元素调用不确定,但是肯定的是在数组中a一定在b前边。
-
遍历数组
-
遍历数组就是将数组中元素都获取到
-
一般情况我们都是使用for循环来遍历数组:
for(var i=0 ; i<数组.length ; i++){ //数组[i] }
-
使用forEach()方法来遍历数组(不兼容IE8)
数组.forEach(function(value , index , obj){ });
-
forEach()方法需要一个函数作为参数:
-
像这种函数,由我们创建但是不由我们调用的,我们称为回调函数。
-
数组中有几个元素,函数就会执行几次。每次执行时,浏览器会将遍历到的元素,以实参的形式传递进来。我们可以来定义形参,来读取这些内容。
-
浏览器会在回调函数中传递三个参数:
value:正在遍历的元素
index:正在遍历元素的索引
obj:被遍历对象
-
-
for … of
for … of是ES6新增的遍历方式,允许遍历一个含有iterator接口的数据结构并且返回各项的值
和for … in的区别如下:
-
for … of遍历获取的是对象的键值,for … in 获取的是对象的键名
-
for … in会遍历对象的整个原型链,性能非常差不推荐使用,而for … of只遍历当前对象不会遍历原型链
-
对于数组的遍历,for … in会返回数组中所有可枚举的属性(包括原型链上可枚举的属性),for … of只返回数组的下标对应的属性值
-
对于普通对象,没有部署原生的 iterator 接口,直接使用 for...of 会报错
-
forEach 循环无法中途跳出,break 命令或 return 命令都不能奏效,for...of 循环可以与break、continue 和 return 配合使用,跳出循环
-
无论是 for...in 还是 for...of 都不能遍历出 Symbol 类型的值,遍历 Symbol 类型的值需要用 Object.getOwnPropertySymbols() 方法
-
总之,for...in 循环主要是为了遍历对象而生,不适用于遍历数组
for...of 循环可以用来遍历数组、类数组对象,字符串、Set、Map 以及 Generator 对象
-
包装类
-
在JS中为我们提供了三个包装类:
String() Boolean() Number()
-
通过这三个包装类可以创建基本数据类型的对象
-
但是在实际应用中千万不要这么干。使用基本数据类型的对象,在做一些比较时 可能会带来一些不可预期的结果。
-
-
方法和属性能添加给对象,不能添加给基本数据类型。
-
当我们去操作一个基本数据类型的属性和方法时,解析器会临时将其转换为对应的包装类,然后再去操作属性和方法,操作完成以后再将这个临时对象进行销毁。
Boolean
• Boolean 类型是与布尔值对应的引用类型。
• 可以采用这种方式创建:
var booleanObject = new Boolean(true);
• 我们最好永远不要使用Boolean包装类。
Number
• Number是数值对应的引用数据类型。创建Number对象只需要在调用构造函数时传递一个数值:
var num = new Numbaer(20);
• 使用数值时我们建议使用基本数值,而不建议使用包装类。
Date
-
日期的对象,在JS中通过Date对象来表示一个时间
-
创建对象
- 创建一个当前的时间对象
var d = new Date();
- 创建一个指定的时间对象
var d = new Date("月/日/年 时:分:秒");
-
方法:
-
getDate()
- 当前日期对象是几日(1-31)
-
getDay()
-
返回当前日期对象时周几(0-6)
- 0 周日
- 1 周一 。。。
-
-
getMonth()
- 返回当前日期对象的月份(0-11)
- 0 一月 1 二月 。。。
-
getFullYear() 从 Date 对象以四位数字返回年份。
-
getHours() 返回 Date 对象的小时 (0 ~ 23)。
-
getMinutes() 返回 Date 对象的分钟 (0 ~ 59)。
-
getSeconds() 返回 Date 对象的秒数 (0 ~ 59)。
-
getMilliseconds() 返回 Date 对象的毫秒(0 ~ 999)。
-
getTime()
-
返回当前日期对象的时间戳
-
时间戳,指的是从1970年月1日 0时0分0秒,到现在时间的毫秒数
计算机底层保存时间都是以时间戳的形式保存的。
-
-
Date.now()
-
可以获取当前代码执行时的时间戳
-
-
Math
-
Math属于一个工具类,它不需要我们创建对象,它里边封装了属性运算相关的常量和方法
我们可以直接使用它来进行数学运算相关的操作
-
方法:
-
Math.PI
- 常量,圆周率
-
Math.abs()
- 绝对值运算
-
Math.ceil()
- 向上取整,小数位只要有值就自动进1
-
Math.floor()
- 向下取整
-
Math.round()
- 四舍五入取整
-
Math.random() 可以用来生成一个0-1之间的随机数。 开区间(0,1)
- 生成一个0-10的随机数:Math.round(Math.random() * 10) 生成一个0-x之间的随机数:Math.round(Math.random() * x) 生成一个1-10:Math.round(Math.random() * ( 10 - 1 ) + 1) 生成一个x-y之间的随机数:Math.round(Math.random() * ( y - x ) + x)
-
Math.pow(x,y)
- 求x的y次幂
-
Math.sqrt()
- 对一个数进行开方
-
Math.max()
- 求多个数中最大值
-
Math.min()
- 求多个数中的最小值
-
String
-
length
- 获取字符串的长度
- 在底层字符串是以字符数组的形式保存的。["H","e","l"]
-
charAt()
- 根据索引获取指定的字符
-
charCodeAt()
- 根据索引获取指定的字符编码
-
String.fromCharCode(s)
- 根据字符编码获取字符
-
concat()
- 用来连接两个或多个字符串(作用和+一样)
-
indexOf()、lastIndexOf()
-
从一个字符串中检索指定内容
-
需要一个字符串作为参数,这个字符串就是要检索的内容,
如果找到该内容,则会返回其第一次出现的索引,如果没有找到则返回-1。
-
可以指定一个第二个参数,来表示开始查找的位置
-
indexOf()是从前向后找
-
lastIndexOf()是从后向前找
-
-
slice()
-
可以从一个字符串中截取指定的内容,并将截取到内容返回,不会影响原变量
-
参数:
第一个:截取开始的位置(包括开始)
第二个:截取结束的位置(不包括结束)
-
可以省略第二个参数,如果省略则一直截取到最后
-
可以传负数,如果是负数则从后往前
-
-
-
substr()
- 和slice()基本一致,不同的是它第二个参数不是索引,而是截取的数量
-
substring()
-
和slice()基本一致,不同的是它不能接受负值作为参数,如果设置一个负值,则会自动修正为0
substring()中如果第二个参数小于第一个,自动调整位置
-
-
toLowerCase()
- 将字符串转换为小写并返回
-
toUpperCase()
- 将字符串转换为大写并返回
-
split()
-
可以根据指定内容将一个字符串拆分为一个数组
-
参数:
-
需要一个字符串作为参数,将会根据字符串去拆分数组
如果传递一个空串作为参数,则会将每个字符都拆分为数组中的一个元素。
可以接收一个正则表达式,此时会根据正则表达式去拆分数组
-
-
-
match()
-
可以将字符串中和正则表达式匹配的内容提取出来
-
默认情况下我们的match只会找到第一个符合要求的内容,找到以后就停止检索。我们可以设置正则表达式为全局匹配模式,这样就会匹配到所有的内容。可以为一个正则表达式设置多个匹配模式,且顺序无所谓。
-
match()会将匹配到的内容封装到一个数组中返回,即使只查询到一个结果。
s="A man, a plan, a canal: Panama" var ss=s.toLowerCase().match(/[a-z0-9]+/g); //[ 'a', 'man', 'a', 'plan', 'a', 'canal', 'panama' ] var res=ss.join(""); //amanaplanacanalpanama
-
-
replace()
-
可以将字符串中指定内容替换为新的内容
-
参数:
-
第一个:被替换的内容,可以是一个正则表达式
-
第二个:替换的新内容
-
默认只会替换第一个
-
-
-
search()
-
可以搜索字符串中是否含有指定内容。
-
如果搜索到指定内容,则会返回第一次出现的索引,如果没有搜索到返回-1。
-
它可以接受一个正则表达式作为参数,然后会根据正则表达式去检索字符串。
-
serach()只会查找第一个,即使设置全局匹配也没用。
-
正则表达式(RegExp)
正则用来定义一些字符串的规则,程序可以根据这些规则来判断一个字符串是否符合规则,也可以将一个字符串中符合规则的内容提取出来。
创建正则表达式
- 使用构造函数创建更加灵活(传参数,变量可变)。
-
var reg = new RegExp("正则","匹配模式");
-
- 使用字面量的方式创建更加简单;
-
var reg = /正则表达式/匹配模式
-
语法
匹配模式
- i:忽略大小写
- g:全局匹配模式
- 设置匹配模式时,可以都不设置,也可以设置1个,也可以全设置,设置时没顺序要求
- m:多行匹配
方括号
-
| 或
-
[] 或
-
[ab] == a|b。
-
[a-z] 小写字母
-
[A-Z] 大写字母
-
[A-z] 任意字母(这会出问题,因为在Unicode编码中A-z中存在6个非字母的字符,比如说 ^ 这个字符就属于[A-z]。) 最好[a-z | A-Z]
-
[0-9] 任意数字
-
[^ ] 除了
-
量词
-
通过量词可以设置一个内容出现的次数。
-
量词只对它前边的一个内容起作用。
-
{n} 正好n次
-
{m,n} m-n次
-
{m,} 至少m次
-
+:至少一个,相当于{1,}。
-
*:0个或多个,相当于{0,}。
-
?:0个或1个,相当于{0,1}。
-
元字符(转义字符)
-
\ 在正则表达式中使用\作为转义字符
-
. 表示任意字符
-
. 表示.(小数点)
-
\ 表示\
-
\w:任意字母、数字、_ [A-z0-9_]
-
\W:除了字母、数字、_ [^A-z0-9_]
-
\d:任意的数字 [0-9]
-
\D:除了数字 [^0-9]
-
\s:空格
-
\S:除了空格
-
\b:单词边界 reg=/\bchild\b/ 表示child是一个独立的单词
-
\B:除了单词边界 reg=/\Bchild\B/ 表示child是一个单词的中间段
-
-
注意:使用构造函数时,由于它的参数是一个字符串,而\是字符串中转义字符,如果要使用\则需要使用\来代替。
-
去除字符串前后空格
^ 和$
-
^ 表示开始,$ 表示结束
-
如果在正则表达式中同时使用^ $,则要求字符串必须完全符合正则表达式。
-
方法
-
test()
-
可以用来检查一个字符串是否符合正则表达式,如果符合返回true,否则返回false
-
var reg = new RegExp("a"); 这个正则表达式可以来检查一个字符串中是否含有a。
-
检查手机号例子
创建一个正则表达式,用来检查一个字符串是否是一个合法手机号
手机号的规则:1 3 567890123 (11位)
第1位:以1开头 ^1 第2位:3~9任意数字 [3-9] 第3位及以后:任意数字9个 [0-9]{9}:之后不能再有其它内容。 ^1 [3-9] [0-9]{9}$
邮件的正则例子
电子邮件:hello .nihao @ abc .com.cn 任意字母数字下划线 .任意字母数字下划线 @ 任意字母数字 .任意字母(2-5位) .任意字母(2-5位) \w{3,} (.\w+)* @ [A-z0-9]+ (.[A-z]{2,5}){1,2}