1 JavaScript
1.1 概念
一门客户端脚本语言
- 运行在客户端浏览器中的。每一个浏览器都有JavaScript的解析引擎
- 脚本语言:不需要编译,直接就可以被浏览器解析执行了
功能
- 可以来增强用户和html页面的交互过程,可以来控制html元素,让页面有一些动态的效果,增强用户的体验。
JavaScript发展史
如果没有JavaScript,我们在浏览器端注册账号时,会把注册的表单发送到服务器,如果填写的信息有误不能注册,服务器会隔一段时间才返回错误,需要重新填写,这样就很费时间。
- 1992年,Nombase公司,开发出第一门客户端脚本语言,专门用于表单的校验。命名为:C–,后来更名为:ScriptEase
- 1995年,Netscape(网景)公司,开发了一门客户端脚本语言:LiveScript。后来,请来SUN公司的专家,修改LiveScript,命名为JavaScript
- 1996年,微软抄袭JavaScript开发出JScript语言
- 1997年,ECMA(欧洲计算机制造协会),ECMAScript,就是所有客户端脚本语言的标准。
JavaScript = ECMAScript + JavaScript自己特有的东西(BOM+DOM)
ECMAScript
1.2 与html的结合方式
内部JS
定义<script>
,标签体内容就是js代码
外部JS
定义<script>
,通过src属性引入外部的js文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!--
内部JS
-->
<script>
// 控制浏览器弹出一个警告框
alert("Hello World");
// 让计算机在页面中输出一个内容,document.write()可以向body中输出一个内容
document.write("HelloWorld")
// 向控制台输出一个内容
console.log("HelloWorld")
</script>
<!--
外部JS
-->
<script src="js/a.js"></script>
</head>
<body>
<input type="text">
</body>
</html>
js代码写在标签的属性中:
- 结构与行为耦合,不方便维护,不推荐使用
<!-- 可以将js代码编写到标签的onclick属性中
当我们点击按钮,js代码才会执行
-->
<button onclick="alert('HelloWorld');">点我一下</button>
<!-- 可以将js代码写在超链接的href属性中,这样当点击超链接时,会执行js代码 -->
<a href="javascript:alert('HelloWorld');">HelloWorld</a>
注意:
-
< script > 可以定义在html页面的任何地方,但是定义的位置会影响执行的顺序。
-
< script > 可以定义多个。
1.3 基本语法
注释
- 单行注释://注释内容
- 多行注释:/* 注释内容 */
语法规范
- JS中严格区分大小写
- JS中每一条语句以分号(;)结尾
- 如果不写分号,浏览器会自动添加,但是会消耗一些系统资源,有时候浏览器会加错分号
- JS会忽略多个空格和换行
字面量和变量
字面量:都是一些不可改变的值
- 例如:1,2,3,4,5
- 可以直接使用,但一般不用
变量:可以用来保存字面量,一小块存储数据的内存空间
- Java语言是强类型语言,而JavaScript是弱类型语言。
- 强类型:在开辟变量存储空间时,定义了空间将来存储的数据的数据类型。只能存储固定类型的数据
- 弱类型:在开辟存储空间时,不定义空间将来的存储数据类型,可以存放任意类型的数据。
- 声明变量:
- var 变量名 = 初始化值;
- typeof运算符:获取变量的类型。
- null运算后得到的是object
//定义num类型
var num = 1;
var num2 = 1.2;
var num3 = NaN;
//输出到页面上
document.write(num + "---" + typeof(num) + "<br>");
document.write(num2 + "---" + typeof(num2) + "<br>");
document.write(num3 + "---" + typeof(num3) + "<br>");
标识符
在JS中所有的可以由我们自主命名的都可以称为是标识符
命名规则
- 标识符中可以含有字母、数字、_、$
- 标识符不能以数字开头
- 标识符不能是ES中的关键字或保留字
- 标识符一般采用驼峰命名法
- 首字母小写,每个单词的开头字母大写,其余字母小写
- 例如:helloWorld
- JS底层保存标识符时实际上是采用的Unicode编码
数据类型
数据类型指的就是字面量的类型
- 原始数据类型(基本数据类型)
- number:数字。整数/小数/NaN(not a number 一个不是数字的数字类型)
- string:字符串。字符/字符串 “abc” “a” ‘abc’
- boolean:true和false
- null:专门用来表示一个为空的对象
- undefined:未定义。如果一个变量没有给初始化值,则会被默认赋值为undefined
- 引用数据类型:对象
//基本数据类型——
var a = 123;
var b = a;
a++;
console.log("a = " + a); //a = 124
console.log("b = " + b); //b = 123
//引用数据类型——
var obj = new Object();
obj.name = "猪八戒";
var obj2 = obj;
obj.name = "孙悟空";
console.log(obj); //{name: "孙悟空"}
console.log(obj2); //{name: "孙悟空"}
obj2 = null;
console.log(obj); //{name: "孙悟空"}
console.log(obj2); //null
-
JS中的变量都是保存到栈内存中的
- 基本数据类型的值直接在栈内存中存储
- 值与值之间是独立存在的,修改一个变量不会影响其他的变量
-
对象是保存到堆内存中的,每创建一个新的对象,就会在堆内存中开辟出一个新的空间,而变量保存的是对象的内存地址(对象的引用)
- 如果两个变量保存的是同一个对象引用,当通过一个变量修改属性时,另一个也会受到影响
- 如果两个变量保存的是同一个对象引用,当通过一个变量修改属性时,另一个也会受到影响
-
当比较两个基本数据类型时,就是比较值
-
比较两个引用数据类型时,它是比较的对象的内存地址
var obj = new Object();
var obj2 = new Object();
console.log(obj);
console.log(obj2);
console.log(obj == obj2); //false
String字符串
- 在JS中字符串需要使用引号引起来:
var str = "hello";
- 双引号或者单引号都可以
- 引号不能嵌套,双引号里不能放双引号,单引号里不能放单引号
"你是:'谁啊?'"
,'你是:"谁啊?"'
是正确的"你是:\"谁啊?\""
是正确的(转义字符)
Number数值
- JS中可以表示的数字的最大值:Number.MAX_VALUE
- 如果使用Number表示的数字超过了最大值,则会返回一个Infinity表示正无穷
- 最小的正数:Number.MIN_VALUE
- 如果使用JS进行浮点数运算,可能得到一个不精确的结果
强制类型转换
- 指将一个数据类型强制转换为其他的数据类型
- 类型转换主要指,将其他的数据类型,转换为String、Number、Boolean
转为String
- 方式一:调用被转换数据类型的
toString()
方法- 该方法不会影响到原变量,他会将转换的结果返回
- null和undefined这两个值没有toString方法,调用会报错
var a = 123;
console.log(typeof a);
console.log(a);
a = a.toString();
-
方式二:调用
String()
函数,并将被转换的数据作为参数传递给函数- null和undefined这两个值可以调用,会将null直接转换为字符串“null”,将undefined直接转换为字符串“undefined”
-
方式三:任何值和字符串相加都会转换为字符串,并做拼串操作(方法:加
""
空串)
转为number
-
方式一:使用
Number()
函数- string转number:按照字面值转换。如果字面值不是数字,则转为NaN(不是数字的数字)。如果字符串是一个空串或者是一个全是空格的字符串,则转换为0.
- boolean转number:true转为1,false转为0
- null转number:0
- undefined转number:NaN
-
方式二:
parseInt()
将一个字符串中的有效的整数内容取出来转换为number;parseFloat()
把一个字符串中的有效的小数内容取出来转换为number;- 针对string转number
- 如果对非string使用,会先将其转换为string然后再操作
- 可以利用parseInt对小数进行取整,舍去小数点之后
-
方式三:可以通过为一个值
-0
*1
/1
将其转换为number -
方式四:可以对一个其他的数据类型使用正号+,来将其转换为number
转为boolean
-
方式一:使用Boolean()函数
- number:0或NaN为假,非0为真
- string:除了空字符串“”,其他都是true
- null,undefined:都是false
- 对象:都会true
-
方式二(隐式类型转换):将一个其他的数据类型转换为布尔值(可以为一个任意数据类型取两次反)
其他进制的数字
在JS中,如果需要表示16进制的数字则需要以0x开头,8进制以0开头,2进制以0b
- 可以在parseInt()中再传递一个参数,来指定数字的进制,parseInt(a,10)十进制
运算符
通过运算符可以对一个或者多个值进行运算
typeof运算符
可以获得一个值的类型,将该值的类型以字符串的形式返回
算数运算符
+ - * / %
+
:可以对两个值进行加法运算,并将结果返回- 对非number类型的值进行运算时,会将这些值转换为number然后再进行运算
- 任何值和NaN做运算都得NaN
- 如果对两个字符串进行加法运算,则会做“拼串”效果
- 任何值和字符串做加法运算都会先转换为字符串,再和字符串做拼串的操作
result = true + 1;
console.log(result); // 2
console.log(typeof result); // number
result = "123" + "456";
console.log(result); // 123456
console.log(typeof result); // string
result = "1" + 2 + 3; // 123
result = 1 + 2 + "3"; // 33
console.log("result=" + result);
console.log(typeof result); // string
+
""
,将任何值转换为字符串
-
result = 100 - "1"; // 99
*
、/
result = 100 * "2"; // 200
result = 100 * null; // 0
var d = "123";
d = d - 1;
console.log(d); // 122
console.log(typeof d); // number
可以通过为一个值
-0
*1
/1
将其转换为number
%
取模运算(取余数)
一元运算符
只有一个运算数的运算符 ++ --,+(正号) -(负号)
- ++(–)在前,先自增(自减),再运算
- ++(–)在后,先运算,再自增(自减)
理解自增自减:
- a是一个变量,而a++、++a是一个表达式
- 无论a++还是++a都会立即使原变量的值自增1
- 不同的是a++ 和 ++a的值不同
- a++的值等于原变量的值(自增前的值)
- ++a的值等于原变量新值(自增后的值)
var a = 1;
// console.log(a++); //1
console.log(++a); //2
console.log(a); //2
- 正号:不会对数字产生任何影响
- 负号:负号可以对数字进行负号的取反
正负号注意:
- 它会先将运算数转换为number,然后再运算
可以对一个其他的数据类型使用+,来将其转换为number,原理和Number()函数一样
var a = true;
a = +a;
console.log("a = " + a); // a = 1
console.log(typeof a); //number
赋值运算符
= += -= *= /= %=
关系运算符
比较两个值之间的大小,如果关系成立返回true,关系不成立返回false
> < <= >= == !=
- 非数值:
- 先将其转换为数字再比较
- 任何值和NaN做比较都是false
- 注意:如果符号两边都是字符串,不会将其转换为数字进行比较,而会分别比较字符串的Unicode编码(按照字典顺序进行比较。按位注意比较,如果两位一样则比较下一位)
== !=
- 类型相同:直接比较
- 类型不同:先进行类型转换(转换成数字),再比较
注意
console.log(null == "0"); //false
console.log(undefined == "0"); //false
console.log(null == undefined); //true
NaN不和任何值相等,包括它本身
- 不能通过==判断一个值是否为NaN
- 可以通过isNaN函数来判断
===
全等
在比较之前先判断类型,如果类型不一样,则直接返回false
!==
不全等
在比较之前先判断类型,如果类型不一样,则直接返回true
Unicode编码
- 在字符串中使用转义字符输入Unicode编码:
"\u四位十六进制Unicode编码"
console.log("\u0031"); //1
- 在网页中使用Unicode编码:
&#编码;
这里的编码是10进制的
<h1>☠</h1>
逻辑运算符 && || !
- !非:对一个值进行非运算
- 对一个布尔值进行取反操作
- 对非布尔值运算会将其先转换为布尔值再运算
利用该特点,来将一个其他的数据类型转换为布尔值(可以为一个任意数据类型取两次反)
- &&与:对符号两侧的值进行与运算并返回结果
JS中的“与”属于短路的与:
- 如果第一个值为false,不会检查第二个值
- 如果第一个值为true,会检查第二个值
- ||或:对符号两侧的值进行或运算并返回结果
JS中的“与”属于短路的或:
- 如果第一个值为false,会检查第二个值
- 如果第一个值为true,不会检查第二个值
&& || 的非布尔值情况
- 会将其先转换为布尔值,然后再运算,并返回原值
- 与运算:
- 如果第一个值为true,返回第二个值
- 如果第一个值为false,返回第一个值
- 或运算:
- 如果第一个值为true,返回第一个值
- 如果第一个值为false,返回第二个值
三元(条件)运算符 ?:
- 语法:表达式?语句1:语句2
执行流程:
- 首先对条件表达式进行求值
- 如果该值为true,则执行语句1,并返回执行结果
- 如果该值为false,则执行语句2,并返回执行结果
var a = 30;
var b = 43;
var c = 50;
//var max = a > b ? a : b;
//max = max > c ? max : c;
var max1 = (a > b ? a : b) > c ? (a > b ? a : b) : c;
var max2 = a > b ? (a > c ? a : c) : (b > c ? b : c);
console.log(max1);
console.log(max2);
如果表达式的求值结果是非布尔值,则会转换为布尔值再运算
逗号运算符
使用,
可以分割多个语句,一般可以在声明多个变量时使用
var a,b,c;
运算符优先级
- 越靠上优先级越高
- 优先级一样,从左往右运算
1.4 流程控制语句
语句
- 程序由一条一条语句构成
- 语句是按照自上向下的顺序一条一条执行的
- 在JS中可以使用{}来为语句进行分组
代码块
- 同一个{}中的语句我们成为是一组语句
- 他们要么都执行,要么都不执行
- 一个{}中的语句我们也称为一个代码块
特殊语法
- 语句以;结尾,如果一行只有一条语句则;可以省略
- 变量的定义可以使用var关键字,也可以不使用(用var,定义的是局部变量;不用var,定义的是全局变量)
JS中的语句是从上到下一行一行执行的
- 通过流程控制语句可以控制程序执行流程,使程序可以根据一定的条件来选择执行
语句分类
- 条件判断语句
- 条件分支语句
- 循环语句
条件判断语句
if语句
语法一
if(条件表达式)
一条语句
if(条件表达式){
多条语句
}
语法二
if(条件表达式) {
语句...
} else {
语句...
}
语法三
该语句中,只会有一个代码块被执行,一旦代码块执行力,则直接结束语句
if(条件表达式) {
语句...
} else if(条件表达式) {
语句...
} else if(条件表达式) {
语句...
} else {
语句...
}
练习
从键盘输入小明的期末成绩:
当成绩为100时,‘奖励一辆BMW’
当成绩为[80-99]时,‘奖励一台iphone15s’
当成绩为[60-80]时,‘奖励一本参考书’
其他时,什么奖励也没有
prompt()函数
prompt()
函数可以弹出一个提示框,该提示框中会带有一个文本框,用户可以在文本框中输入一段内容
- 该函数需要一个字符串作为参数,该字符串将会作为提示框的提示文字
- 用户输入的内容将会作为函数的返回值返回,可以定义一个变量接受该内容
- prompt()函数的返回值是string类型
- 可以利用
+prompt()
转换为number
- 可以利用
var point = prompt('请输入小明的成绩:');
if (point > 100 || point < 0 || isNaN(point)) {
alert('错误');
} else {
if (point == 100) {
alert('奖励一辆BMW');
} else if (point > 80) {
alert('奖励一台iphone15s');
} else if (point >= 60) {
alert('奖励一本参考书');
} else {
alert('什么奖励也没有');
}
}
大家都知道,男大当婚,女大当嫁。那么女方家长要嫁女儿,当然要提出一定的条件:
高:180cm以上; 富:1000万以上; 帅:500以上;
如果这三个条件同时满足,则:‘我一定要嫁给他’
如果三个条件有为真的情况,则:‘嫁吧,比上不足,比下有余。’
如果三个条件都不满足,则:‘不嫁!’
var height = prompt('你的身高是多少厘米?');
var money = prompt('你有多少万存款');
var handsome = prompt('长得帅吗(指数px)?');
if (height > 180 && money > 1000 && handsome > 500) {
alert("我一定要嫁给他");
} else if (height > 180 || money > 1000 || handsome > 500) {
alert("嫁吧,比上不足,比下有余。");
} else if (! (height > 180) && !(money > 1000) && !(handsome > 500)) {
alert("不嫁!");
}
编写程序,由键盘输入三个整数分别存入变量num1、num2、num3,
对他们进行排序,并且从小到大输出。
var temp;
if (num1 > num2) {
temp = num2;
num2 = num1;
num1 = temp; // num1是较小值,num2是较大值
} else if (num2 > num3) {
temp = num3;
num3 = num2;
num2 = temp; // num2是较小值,num3是最大值
} else if (num1 > num2) {
temp = num2;
num2 = num1;
num1 = temp; // num1是最小值,num2是中间值
}
alert(num1 + "<" + num2 + "<" + num3);
var num1 = +prompt("请输入第一个整数");
var num2 = +prompt("请输入第二个整数");
var num3 = +prompt("请输入第三个整数");
if (num1 < num2 && num1 < num3) {
// num1最小
if (num2<num3) {
//num1<num2<num3
alert(num1 + "<" + num2 + "<" + num3)
} else {
//num1<num3<num2
alert(num1 + "<" + num3 + "<" + num2)
}
} else if (num2 < num1 && num2 < num3) {
// num2最小
if (num1 <num3) {
//num2<num1<num3
alert(num2 + "<" + num1 + "<" + num3)
} else {
//num2<num3<num1
alert(num2 + "<" + num3 + "<" + num1)
}
} else {
// num3最小
if (num1 <num2) {
//num3<num1<num2
alert(num3 + "<" + num1 + "<" + num2)
} else {
//num3<num2<num1
alert(num3 + "<" + num2 + "<" + num1)
}
}
switch语句
条件分支语句
switch(条件表达式) {
case 表达式:
语句...
break;
case 表达式:
语句...
break;
......
default:
语句...
break;
}
执行流程
- 在执行时会依次将case后的表达式的值和switch后的条件表达式的值进行全等比较
- 如果比较结果为true,则从当前case处开始执行代码(包括case后),遇到break推出switch语句
- 如果比较结果为false,则继续向下比较
- 如果所有的比较结果都为false,则只执行default后的语句
对于成绩大于60分的,输出’合格’。低于60分的,输出’不合格’
var score = +prompt("please");
switch (score>= 60) {
case true:
alert("合格");
break;
default:
alert("不合格");
break;
var score = 60;
switch (parseInt(score / 10)) {
case 10:
case 9:
case 8:
case 7:
case 6:
console.log("合格");
break;
default:
console.log("不合格");
break;
}
?在java中可以接受的数据类型:byte int short char 枚举 String
?JavaScript可以接受任意类型
while
while(条件表达式) {
语句...
}
- 先对条件表达式进行求值判断,如果为true则执行循环体;循环体执行完毕后继续对表达式进行判断,如果为true继续执行循环体…遇到false终止循环
- 使用break可以终止循环
创建一个循环需要三个步骤:
- 初始化一个变量
- 在循环中设置一个条件表达式
- 定义一个更新表达式,每次更新初始化变量
do…while
do {
语句...
} while(条件表达式)
- 先执行循环体
- 循环体执行完毕,对条件表达式进行判断…
for
for(①初始化表达式;②条件表达式;④更新表达式) {
③语句...
}
① 执行初始化表达式
② 执行条件表达式,判断是否执行循环
- 如果为true,则执行循环③
- 如果为false终止循环
④ 执行更新表达式,继续重复②
for循环中的三个部分可以省略也可以写在外部
var i = 0;
for(;i<10;) {
alert(i++);
}
for(;;){
//死循环
}
案例:99乘法表
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>九九乘法表</title>
<style>
td{
border: 1px solid;
}
</style>
<script>
document.write("<table align='center'>");
//1.完成基本的for循环嵌套,展示乘法表
for (var i = 1; i <= 9; i++) {
document.write("<tr>");
for (var j = 1; j <= i; j++) {
document.write("<td>")
//输出 1*1=1
document.write(i + "*" + j + "=" + (i * j) + "  ");
document.write("</td>");
}
/*//输出换行
document.write("<br>");*/
document.write("<tr>")
}
//2.完成表格的嵌套
document.write("</table>")
</script>
</head>
<body>
</body>
</html>
break和continue
-
break关键字可以用来退出switch或循环语句
- break关键字会立即终止离他最近的那个循环语句
- if语句不能用break和continue
-
可以为循环语句创建一个label,来标识当前的循环
label:循环语句
- 使用break语句时,可以在break后跟着一个label
- 将会结束指定的循环,而不是最近的
-
continue关键字可以跳过当次循环
- continue默认只会对离他最近的循环起作用
代码执行时间
开始计时:console.time("计时器命名");
计时结束:console.timeEnd("计时器命名");
在控制台可以看到计时的时间2
开方
Math.sqrt();
对一个数进行开方
2 对象
基本数据类型与对象
- 基本数据类型都是单一的值,值和值之间没有任何的联系
在JS中表示一个人的信息(name gender age):var name = "孙悟空"
,var gender = "男"
,var age = 18;
- 对象属于一种复合的数据类型,在对象中可以保存多个不同数据类型的属性
2.1 对象简介
对象分类
- 内建对象
- 由ES标准中定义的对象,在任何的ES的实现中都可以使用
- 比如:Math String Number Boolean Function Object…
- 宿主对象
- 由JS的运行环境提供的对象,目前来讲主要指浏览器提供的对象
- 比如:BOM DOM
- 自定义对象
- 由开发人员自己创建的对象
对象的基本操作
var obj = new Object();
创建对象
- 使用new关键字调用的函数,是构造函数constructor
- 构造函数是专门用来创建对象的函数
- 使用typeof检查一个对象时,会返回object
obj.name = "孙悟空";
向对象添加属性
- 在对象中保存的值称为属性
- 语法:对象.属性名 = 属性值
console.log(obj.name);
读取对象中的属性
- 语法:对象.属性名
- 如果读取对象中没有的属性,不会报错而是返回undefined
obj.name = "tom";
修改对象的属性值
- 语法:对象.属性名 = 新值
delete obj.name;
删除属性
- 语法:delete 对象.属性名
属性名
- 对象的属性名不强制要求遵守标识符的规范,但是尽量按照标识符的规范去做。
obj.var = "hello";
是对的 - 如果要使用特殊的属性名,不能采用“对象.属性名 = 属性值”的方式,需要另一种方式:
- 语法:对象[“属性名”] = 属性值
- 如:
obj["123"] = 789;
console.log(obj["123"]);
- 在使用[]这种形式去操作属性,更加的灵活
- 在[]中可以直接传递一个变量,这样变量值是多少就会读取那个属性
- 如:
var n = "123";
console.log(obj[n]);
属性值
- JS对象的属性值,可以是任意的数据类型,也可以是一个对象
var obj = new Object();
obj.name = "tom";
var obj2 = new Object();
obj2.sex = "female";
obj.test = obj2;
console.log(obj); //{name: "tom", test: {…}}
console.log(obj.test); //{sex: "female"}
console.log(obj.test.sex); //female
in 运算符
通过该运算符可以检查一个对象中是否含有指定的属性,有返回true,没有返回false
- 语法:
"属性名" in 对象
对象字面量
使用对象字面量来创建一个对象
var obj = {};
- 使用对象字面量,可以在创建对象时,直接指定对象中的属性
- 语法:{属性名:属性值,属性名:属性值…}
var obj2 = {name:"猪八戒"};
- 对象字面量的属性名可以加引号也可以不加,建议不加
- 如果要使用一些特殊的名字,子必须加引号
2.2 函数function
- 函数也是一个对象
- 函数中可以封装一些功能(代码),在需要时可以执行这些功能(代码)
- 函数中可以保存一些代码在需要的时候调用
- 使用typeof检查一个函数对象时,会返回function
函数对象
var fun = new Function();
创建一个函数对象
- 可以将要封装的代码以字符串的形式传递给构造函数
var fun = new Function("console.log('Hello 这是我的第一个函数')");
- 封装到函数中的代码不会立即执行
- 函数中的代码会在函数调用的时候执行
- 调用函数语法:函数对象(),
fun()
- 当调用函数时,函数中封装的代码会按照顺序执行
函数也是对象(它具有所有普通对象的功能),在实际开发中很少使用构造函数来创建一个对象
1.使用函数声明来创建一个函数:
- 语法:
function 函数名([形参1, 形参2... 形参N]) {
语句...
}
[ ]里代表可有可无
2.使用函数表达式来创建一个函数
var 函数名 = function ([形参1, 形参2... 形参N]) {
语句...
};
函数的参数
- 可以在函数的()中来指定一个或多个形参(形式参数)
- 多个形参之间使用逗号隔开,声明形参就相当于在函数内部声明了对应的变量
- 在调用函数时,可以在()中指定实参(实际参数),实参将会赋值给函数中对应的形参
- 调用函数时解析器不会检查实参的类型和数量
- 注意是否可能接收到非法的参数,如果有可能则需要对参数进行类型的检查
- 函数实参可以是任意数据类型
实参是对象
function test(o) {
console.log(o);
console.log(o.name + o.age + o.gender + o.address);
}
var obj = {
name: "孙悟空",
age: 18,
gender: "男",
address: "花果山"
};
test(obj);
实参是函数
function fun(a) {
//console.log("a = " + a);
a(obj);
}
fun(test);
实参是匿名函数:将一个匿名函数作为实参传递给一个函数
function fun(a) {
console.log("a = " + a);
}
fun(function(){alert("hello")}); //a = function(){alert("hello")}
- 多余实参不会被赋值
- 如果实参的数量少于形参数量,则没有对应实参的形参将是undefined
function sum(a, b) {
console.log(a + b);
}
sum(1); //NaN
注意:
- test()
- 调用函数
- 相当于使用的函数的返回值
- test
- 函数对象
- 相当于直接使用函数对象
函数的返回值
- 可以使用return来设置函数的返回值
- 语法:return 值;
- return后的值将会作为函数的执行结果返回
- 在函数中return后的语句都不会执行
- 如果return语句后不跟任何值就相当于返回一个undefined
- return后可以跟任意类型的值
return返回一个对象
function fun() {
return {name:"沙和尚"};
}
console.log(fun().name);
return返回一个函数
function fun2() {
function fun3() {
alert("我是fun3");
}
return fun3;
}
console.log(fun2());
fun2()();
立即执行函数
函数定义完,立即被调用
(function() {
alert("我是一个匿名函数");
})();
方法
对象.方法
函数作为对象的属性时,我们称这个函数是这个对象的方法,调用函数就说调用对象的方法
var obj = new Object();
obj.name = "孙悟空";
obj.age = 18;
obj.sayName = function() {
console.log(obj.name);
};
//console.log(obj.sayName);
//调方法
obj.sayName();
call()和apply()
这两个方法都是函数对象的方法,需要通过函数对象来调用
- 当对函数调用call()和apply()都会调用函数执行
- 在调用call()和apply()可以将一个对象指定为第一个参数
- 此时这个对象将会成为函数执行时的this
function fun() {
alert(this.name);
}
var obj = {
name: "obj",
sayName:function() {
alert(this.name)
}
};
var obj2 = {
name: "obj2"
};
// fun.apply(obj); //obj
// fun.apply(obj2); //obj2
obj.sayName.apply(obj2); //obj2
- call()方法可以将实参在对象之后依次传递
- apply()方法需要将实参封装到一个数组中统一传递
枚举对象中的属性
for(var 变量 in 对象) {
}
for...in
语句 对象中有几个属性,循环体就会执行几次- 每次执行时,会将对象中的一个属性的名字赋值给变量
var obj = {
name: "孙悟空",
age: 18,
gender: "男",
address: "花果山"
};
for (var n in obj) {
console.log(obj[n]);
}
作用域
作用域指一个变量的作用的范围
全局作用域
- 直接编写在script标签中的JS代码,都在全局作用域
- 全局作用域在页面打开时创建,在页面关闭时销毁
- 在全局作用域中有一个全局对象window,我们可以直接使用
- 它代表的是一个浏览器窗口,由浏览器创建
- 在全局作用域中
- 创建的变量都会作为window对象的属性保存
- 创建的函数都会作为window对象的方法保存
- 全局作用域中的变量都是全局变量,在页面中的任意部分都可以访问到
变量的声明提前
- 使用var关键字声明的变量,会在所有的代码执行之前被声明(但是不会赋值)
console.log("a = " + a); // a = undefined
var a = 123;
- 如果声明变量时不适用var关键字,则变量不会被声明提前
- 相当于在代码最上面写了:
var a;
console.log("a = " + a); // a is not defined
a = 123;
函数的声明提前
- 使用函数声明形式创建的函数 function 函数(){},它会在所有的代码执行之前就被创建,相当于在代码最上面创建了这个函数
fun();
function fun() {
console.log("我是fun函数"); // 我是fun函数
}
- 使用函数表达式创建的函数,不会被声明提前,所以不能提前调用
fun2(); // fun2 is not a function
var fun2 = function() {
console.log("我是fun函数2");
}
函数作用域
- 调用函数时创建函数作用域,函数执行完毕以后,函数作用域销毁
- 每调用一次函数就会创建一个新的函数作用域,他们之间是相互独立的
- 在函数作用域中可以访问到全局作用域的变量,在全局作用域中无法访问到函数作用域的变量
- 在函数作用域操作一个变量时,它会先在自身作用域中寻找,如果有直接使用,如果没有则向上一级作用域中寻找
- 在函数作用域中也有提前声明的特性
- 使用var关键字声明的变量,会在函数中所有代码执行之前被声明
- 函数声明也会在函数中所有的代码执行之前执行
function fun() {
console.log(a); //undefined
var a = 35;
}
fun();
相当于
function fun() {
var a;
console.log(a); //undefined
a = 35;
}
fun();
- 在函数中不使用var声明的变量都会成为全局变量
var a = 10;
function fun() {
console.log(a); //10
a = 20;
d = 100;
}
fun();
console.log(a); //20
console.log(d); //100
- 定义形参就相当于在函数作用域中声明了变量
var e = 23;
function fun(e) {
alert(e); //20
}
fun(20);
var a = 123;
function fun(a){
alert(a); //undefined
a = 456;
}
fun();
alert(a); //123
debug
this
解析器在调用函数每次都会向函数内部传递一个隐含的参数this
- this指向的是一个对象,这个对象我们称为函数执行的上下文对象
- 根据函数的调用方式的不同,this会指向不同的对象
- 以函数的形式调用时,this永远都是window
- 以方法的形式调用时,this就是调用方法的那个对象
- 当以构造函数的形式调用时,this就是新创建的对象
- 使用call和apply调用时,this是指定的那个对象
- 在事件的响应函数中,响应函数是给谁绑定的this就是谁
function fun() {
console.log(this); //Window
}
//以函数的形式调用时,this永远都是window
fun();
function fun() {
console.log(this); // {name: "孙悟空", sayName: ƒ}
}
var obj = {
name: "孙悟空",
sayName: fun
};
console.log(obj.sayName == fun); //true
//以方法的形式调用时,this就是调用方法的那个对象
obj.sayName();
function fun() {
console.log(this.name); //全局的name属性
}
var name = "全局的name属性";
fun();
var name = "全局";
function fun(){
console.log(this.name);
}
var obj = {
name:"孙悟空",
sayName:fun
}
var obj2 = {
name:"沙和尚",
sayName:fun
}
fun(); //全局
obj.sayName(); //孙悟空
obj2.sayName(); //沙和尚
使用工厂方法创建对象
function createPerson(name, age, gender) {
var obj = new Object();
obj.name = name;
obj.age = age;
obj.gender = gender;
obj.sayName = function() {
alert(this.name);
};
return obj;
}
function createDog(name, age) {
var obj = new Object();
obj.name = name;
obj.age = age;
obj.sayHello = function() {
alert("www~~~");
};
return obj;
}
var dog = createDog("旺财", 3);
var obj = createPerson("猪八戒", 28, "男");
console.log(dog); //Object { name: "旺财", age: 3, sayHello: sayHello() }
console.log(obj); //Object { name: "猪八戒", age: 28, gender: "男", sayName: sayName() }
2.3 构造函数
创建一个构造函数,专门用来创建Person对象的
- 构造函数就是一个普通的函数,创建方式和普通函数没有区别,不同的是构造函数习惯上首字母大写
- 构造函数和普通函数的调用方式不同
- 普通函数是直接调用,而构造函数需要使用new关键字来调用
//构造函数
function Person() {
}
构造函数的执行流程:
- 立刻创建一个新的对象
- 将新建的对象设置为函数中的this,在构造函数中可以使用this来引用新建的对象
- 逐行执行函数中的代码
- 将新建的对象作为返回值返回
function Person(name, age, gender) {
this.name = name;
this.age = age;
this.gender = gender;
this.sayName = function() {
alert(this.name);
}
}
function Dog(name, age) {
this.name = name;
this.age = age;
this.sayHello = function() {
alert("www~~~");
}
}
var per = new Person("孙悟空", 18, "男");
var dog = new Dog("旺财", 3);
console.log(per); //Person {name: "孙悟空", age: 18, gender: "男", sayName: ƒ}
console.log(dog); //Dog {name: "旺财", age: 3, sayHello: ƒ}
- 使用同一个构造函数创建的对象,我们称为一类对象,也将一个构造函数称为一个类
- 我们将通过一个构造函数创建的对象,称为是该类的实例
instanceof
- 使用instanceof可以检查一个对象是否是一个类的实例
- 语法:
对象 instanceof 构造函数
,返回boolean值 - 所有的对象都是Object的实例
构造函数修改
在Person构造函数中,为每一个对象都添加了一个sayName方法
- 目前是在构造函数内部创建的,也就是构造函数每执行一次就会创建一个新的sayName方法,所有实例的sayName都是唯一的(执行10000次就会创建10000个一样的方法)
- 修改:可以使所有的对象共享同一个方法
- 将sayName方法在全局作用域中定义
function Person(name, age, gender) {
this.name = name;
this.age = age;
this.gender = gender;
this.sayName = fun;
}
function fun() {
alert(this.name);
}
var per = new Person("孙悟空", 18, "男");
var per2 = new Person("白骨精", 16, "女");
per.sayName();
per2.sayName();
console.log(per.sayName == per2.sayName); //true
将函数定义在全局作用域,污染了全局作用域的命名空间,而且定义在全局作用域中也很不安全
原型对象
我们所创建的每一个函数,解析器都会向函数中添加一个属性prototype
- 这个属性对应着一个对象,这个对象就是我们所谓的原型对象
- 如果函数作为普通函数调用prototype没有任何作用
- 当函数以构造函数的形式调用时,它所创建的对象中都会有一个隐含的属性,指向该构造函数的原型对象,我们可以通过
__proto__
来访问该属性(两个下划线)
function MyClass() {
}
//向MyClass的原型中添加属性a
MyClass.prototype.a = 123;
//向MyClass的原型中添加方法
MyClass.prototype.sayHello = function() {
alert("hello");
};
var mc = new MyClass();
var mc2 = new MyClass();
console.log(mc.__proto__ == MyClass.prototype); //true
console.log(mc.a); //123
mc.sayHello(); //alert...
原型对象就相当于一个公共的区域,所有同一个类的实例都可以访问到这个原型对象
- 我们可以将对象中共有的内容,统一设置到原型对象中
- 当我们访问对象的一个属性或方法时,它会先在对象自身中寻找,如果有则直接使用,如果没有则会去原型对象中寻找,如果找到则直接使用
- 以后我们创建构造函数时,可以将这些对象共有的属性和方法,统一添加到构造函数的原型对象中
function Person(name, age, gender) {
this.name = name;
this.age = age;
this.gender = gender;
}
//向原型中添加sayName方法
Person.prototype.sayName = function fun() {
alert(this.name);
};
var per = new Person("孙悟空", 18, "男");
var per2 = new Person("白骨精", 16, "女");
per.sayName();
per2.sayName();
console.log(per.sayName == per2.sayName); //true
hasOwnProperty
- 原型对象也是对象,所以它也有原型
- 当我们使用一个对象的属性或方法时,会先在自身中寻找,
- 自身中如果有则直接使用,如果没有去原型对象中寻找,
- 如果原型对象中有,则使用,如果没有则去原型的原型中寻找,直到找到Object对象的原型
- Object对象的原型没有原型,如果在Object中依然没有找到,则返回undefined
function MyClass() {
}
MyClass.prototype.name = "我是原型中的名字";
var mc = new MyClass();
mc.age = 18;
console.log(mc.name); //我是原型中的名字
// 使用in检查对象中是否含有某个属性时,如果对象中没有但是原型中有,也会返回true
console.log("name" in mc); //true
// 可以使用对象的hasOwnProperty()来检查对象自身中是否含有该属性
// 使用该方法只有对象自身中含有属性时,才会返回true
console.log(mc.hasOwnProperty("age")); //true
console.log(mc.__proto__.__proto__.hasOwnProperty("hasOwnProperty")); //true
console.log(mc.__proto__.__proto__.); //Object的原型
console.log(mc.__proto__.__proto__.__proto__); //null,Object的原型没有原型
console.log(mc.hello); //undefined
toString()?
当我们直接在页面中打印一个对象时,实际是输出对象的toString()方法的返回值
function Person(name, age, gender) {
this.name = name;
this.age = age;
this.gender = gender;
}
Person.prototype.toString = function() {
return "Person[name="+this.name+",age="+this.age+",gender="+this.gender+"]";
};
var per = new Person("孙悟空", 18, "男");
var per2 = new Person("猪八戒", 28, "男");
/* per.toString = function() {
return "Person[name="+this.name+",age="+this.age+",gender="+this.gender+"]";
}; */
var result = per.toString();
// console.log(result);
// console.log(per.__proto__.__proto__.hasOwnProperty("toString"))
console.log(per);
垃圾回收
- JS中有自动的垃圾回收机制,会自动将这些垃圾对象从内存中销毁
- 我们不需要也不能进行垃圾回收
- 我们需要做的只是将不再使用的对象设置为null
3 内建对象
3.1 Array对象
数组也是一个对象
- 它和我们普通对象功能类似,也是用来存储一些值
- 不同的是普通对象是使用字符串作为属性名的
- 数组使用数字来作为索引操作元素
- 索引是从0开始的整数
数组的存储性能比普通对象要好,在开发中我们经常使用数组来存储一些数据
数组基本操作
创建数组对象:var arr = new Array();
向数组中添加元素:
- 语法:数组[索引] = 值;
读取数组中的元素:
- 语法:数组[索引]
- 如果读取不存在的索引,会返回undefined
获取数组的长度:
- 语法:数组.length
- 对于连续的数组,使用length可以获取到数组的长度(元素的个数)
- 对于非连续数组,使用length会获取到数组的最大的索引+1
- 修改length:如果修改的length大于原长度,则多出部分空出来
- 如果修改的length小于原长度,多余的部分会被删除
向数组的最后一位添加元素:arr[arr.length] = 3;
var arr = new Array();
arr[0] = 10;
arr[1] = 33;
arr[2] = 22;
arr[10] = 31;
console.log(arr.length); // 11
数组字面量
使用字面量来创建数组:var arr = [1,2,3,4,5,10];
、var arr2 = new Array(12,2,4);
// 创建一个数组,数组中只有一个元素10
var arr = [10];
console.log(arr); //[10]
// 创建一个长度为10的数组
var arr2 = new Array(10);
console.log(arr2.length); //10
- 数组中的元素可以是任意数据类型
// 数组中的元素可以是任意数据类型
arr = ["hello", 1, true, null, undefined];
var obj = {
name: "悟空"
};
// 数组中的元素是对象
arr[arr.length] = obj;
// 数组中的元素是函数
arr = [function() {
alert(1);
}, function() {
alert(2);
}]
console.log(arr[1]());
// 数组中的元素是数组,我们成为二维数组
arr = [[1,2,3],[4,5,6],[7,8,9]];
console.log(arr);
数组的方法
- push():向数组的末尾添加一个或更多元素,并返回新的长度。
- pop(): 删除并返回数组的最后一个元素。
- unshift(): 向数组的开头添加一个或更多元素,并返回新的长度。
- shift(): 删除并返回数组的第一个元素
- slice(): 从某个已有的数组返回选定的元素
- start参数:截取开始位置的索引,包含开始索引
- end参数:截取结束位置的索引,不包含结束索引
var arr = ["swk", "zbj", "shs", "ts"];
result = arr.slice(0,2);
console.log(arr); //["swk", "zbj", "shs", "ts"]
console.log(result); //["swk", "zbj"]
-
splice(): 删除数组中指定元素。(影响原数组)将被删除的元素作为返回值返回
- index:规定删除的位置
- howmany:删除几个
-
concat(): 连接两个或更多的数组,并返回结果。
-
join():把数组的所有元素放入一个字符串。元素通过指定的分隔符进行分隔。
- separator:指定要使用的分隔符,默认使用逗号作为分隔符。
-
reverse():颠倒数组中元素的顺序。
-
sort():对数组的元素进行排序
- 默认根据Unicode编码排序
- sortby:规定排序顺序。必须是函数。
var arr = [4, 3,8,9];
var result = arr.sort(function(a,b) {
// 升序
return a-b;
// 降序
// return b-a;
});
console.log(result);
数组的遍历
数组遍历就是将数组中所有的元素都取出来
function Person(name, age) {
this.name = name;
this.age = age;
}
//修改Person原型的toString
Person.prototype.toString = function() {
return "Person[name=" + this.name + ",age=" + this.age + "]";
}
// 创建Person对象
var per = new Person("孙悟空", 18);
var per2 = new Person("猪八戒", 28);
var per3 = new Person("红孩儿", 8);
var per4 = new Person("蜘蛛精", 16);
var per5 = new Person("二郎神", 38);
// 将以上Person对象放入到一个数组中
var perArr = [per, per2, per3, per4, per5];
// 创建一个函数,可以将perArr中的满18岁的Person提取出来
// 然后封装到一个新的数组中并返回
function getAdult(perArr) {
var newArr = [];
for (var i = 0; i < perArr.length; i++) {
if (perArr[i].age >= 18) {
newArr.push(perArr[i]);
}
}
return newArr;
}
result = getAdult(perArr);
console.log(result.toString());
forEach
forEach()方法需要一个函数作为参数
- 一般用回调函数(由我们创建但不由我们调用)作为参数
- 数组中有几个元素函数就会执行几次,每次执行时,浏览器会将遍历到的元素,以实参的形式传递进来,我们可以定义形参来读取这些内容
- 浏览器会在回调函数中传递三个参数
- 第一个参数:当前正在遍历的元素
- 第二个参数:当前正在遍历的元素的索引
- 第三个参数:正在遍历的数组
var arr = ["swk", "zbj", "shs", "ts"];
arr.forEach(function(value,index,obj) {
console.log(value);
});
isArray
判断是否是数组对象
function fun() {
console.log(arguments instanceof Array); //false
console.log(Array.isArray(arguments)); //false
}
fun();
arguments
在调用函数时,浏览器每次都会传递进两个隐含的参数
- 函数的上下文对象this
- 封装实参的对象arguments
arguments 是一个类数组对象,它也可以通过索引来操作数据,也可以获取长度
- 在调用函数时,我们所传递的实参都会在arguments中保存
- arguments.length获取实参的长度
- 即使不定义形参,也可以通过arguments来使用实参
- arguments里有一个属性callee
- 这个属性对应一个函数对象,就是当前正在执行的函数的对象
function fun() {
console.log(arguments.length); //2
console.log(arguments[0]); //hello
console.log(arguments.callee == fun); //true
}
fun("hello",true);
3.2 Date对象
在JS中使用Date对象来表示一个时间
- 当前代码执行的时间
var d = new Date();
console.log(d); //Thu Mar 11 2021 17:31:58 GMT+0800 (中国标准时间)
- 创建一个指定的时间对象
- 日期格式:月份/日/年 时:分:秒
var d = new Date("12/03/2016 11:10:30");
console.log(d); //Sat Dec 03 2016 11:10:30 GMT+0800 (中国标准时间)
方法
- getDate():获取当前日期对象是几日
- getDay():获取当前日期对象是周几(周日是0)
- getMonth():获取当前日期对象是几月(一月是0)
- getFullYear():获取当前日期对象的年份
- getTime():返回 1970 年 1 月 1 日至今的毫秒数(时间戳)
Date.now()
:获取当前的时间戳
3.3 Math对象
Math不是一个构造函数,它属于一个工具类
- 不用创建对象,里面封装了数学运算相关的属性和方法
方法
- Math.PI:表示圆周率
- abs():可以用来计算一个数的绝对值
- ceil(x):对数进行上舍入(向上取整)
- floor(x):对数进行下舍入(向下取整)
- round(x):把数四舍五入为最接近的整数
- random(): 返回 0 ~ 1 之间的随机数
//生成0-10随机数
console.log(Math.round(Math.random()*10));
//生成1-10随机数
console.log(Math.round(Math.random()*9)+1);
生成x-y随机数:Math.round(Math.random()*(y-x)+x)
- max(x,y):返回 x 和 y 中的最大值
- min(x,y):返回 x 和 y 中的最小值
- pow(x,y):返回x的y次幂
- sqrt(x):返回x的平方根
3.4 包装类
通过包装类可以将基本数据类型的数据转换为对象
- String:可以将基本数据类型字符串转换为String对象
- Number:可以将基本数据类型数字转换为Number对象
- Boolean:可以将基本数据类型布尔值转换为Boolean对象
方法和属性只能添加给对象,不能添加给基本数据类型
- 当我们对一些基本数据类型的值去调用属性和方法时,浏览器会临时使用包装类将其转换为对象,然后再调用对象的属性和方法
- 调用完之后再将其转换为基本数据类型
var s = 123;
s = s.toString();
console.log(s); //123
console.log(typeof s); //string
s.hello = "你好";
console.log(s.hello); //undefined
String对象的方法
在底层字符串是以字符数组的形式保存的
var str = "Hello Atguigu";
console.log(str.length); //13
console.log(str[4]); //o
字符串方法
- charAt():返回在指定位置的字符
- charCodeAt():返回在指定的位置的字符的 Unicode 编码
- fromCharCode(): 从字符编码创建一个字符串
- concat():连接字符串
- indexOf():检索字符串是否含有指定内容
- 如果字符串含有该内容,则会返回其第一次出现的索引
- 如果没有找到指定的内容,则返回-1
- searchvalue:查找的内容
- fromindex:指定开始查找的位置
- lastIndexOf():与indexOf一样,只是从后往前找
- slice():提取字符串的片断
- substring():提取字符串中两个指定的索引号之间的字符。
- 和slice()类似
- 不同的是这个方法不能接收负值
- 如果传递了一个负值,则默认使用0
- 如果第二个参数小于第一个,则自动交换
- substr():从起始索引号提取字符串中指定数目的字符
- split():把字符串分割为字符串数组
- 需要一个字符串作为参数,将会根据该字符串去拆分数组
- toLowerCase():把字符串转换为小写。
- toUpperCase():把字符串转换为大写。
3.5 正则表达式
是一个对象
简介
语法:var 变量 = new RegExp("正则表达式","匹配模式");
方法:test()
检查一个字符串是否符合正则表达式的规则,返回 true 或 false。
- 匹配模式 i :执行对大小写不敏感的匹配
var str = "Abn";
//检查一个字符串里是否有a(不区分大小写)
var reg = new RegExp("a","i");
console.log(reg.test(str)); // true
语法
使用字面量来创建正则表达式
语法:var 变量 = /正则表达式/匹配模式;
- 使用
|
表示或者的意思 []
里的内容也是或的关系- [ab] == a|b
- [0-9] 查找任何从 0 至 9 的数字。
- [a-z] 查找任何从小写 a 到小写 z 的字符。
- [A-Z] 查找任何从大写 A 到大写 Z 的字符。
- [A-z] 查找任何从大写 A 到小写 z 的字符。
// 检查一个字符串是否含有abc或adc或aec
var reg = /a[bde]c/;
console.log(reg.test("cadcefg")); //true
[^adc]
:查找abc以外的
字符串与正则
- split():把字符串分割为字符串数组
- 不指定全局匹配也会全部拆分
var str = "1a2b3c4d5e6f7";
var result = str.split(/[A-z]/);
console.log(result); //["1", "2", "3", "4", "5", "6", "7"]
console.log(result.length); //7
- search():检索与正则表达式相匹配的值
- 搜索到指定内容则会返回第一次出现的索引,搜索不到返回-1
- 不能全局匹配,只会查找第一个
var str = "hello abc hello abc";
var result = str.search("abc");
console.log(result); //6
var str = "hello acc hello aec afc";
var result = str.search(/a[bef]c/);
console.log(result); //16
- match():根据正则表达式,从一个字符串中将符合条件的内容提取出来,返回数组
- 默认情况下match只会找到第一个符合要求的内容,找到以后就会停止检索
- 设置正则表达式为全局匹配模式,这样就会匹配到所有的内容
var str = "1a2b3c4d5e6f7BC5D";
var result = str.match(/[a-z]/gi);
console.log(result); //["a", "b", "c", "d", "e", "f", "B", "C", "D"]
- replace():将字符串中指定内容替换为新的内容
- 参数:被替换的内容,新内容
- 默认只会替换第一个
var str = "1a2a3c4d5e6f7BC5D";
var result = str.replace(/[A-z]/gi,"");
console.log(result); //12345675
正则表达式语法
量词
通过量词可以设置一个内容出现的次数
- n{X}:匹配包含 X 个 n 的序列的字符串
var reg = /a{3}/; //aaa
reg = /(ab){3}/; //ababab
reg = /ab{3}c/; //abbbc
- n{X,Y}:匹配包含 X 至 Y 个 n 的序列的字符串
reg = /as{1,3}f/; //asf,assf,asssf
reg = /as{2,}f/; //s三次以上
- n+:至少一个,相当于{1,}
- n*:0个或多个,相当于{0,}
- n?:0个或1个,相当于{0,1}
- ^n:匹配任何开头为 n 的字符串
- n$:匹配任何结尾为 n 的字符串
var reg = /^a$/; //只能有a
var reg = /^a|a$/; //以a开头或结尾
- ?=n:匹配任何其后紧接指定字符串 n 的字符串
- ?!n:匹配任何其后没有紧接指定字符串 n 的字符串
手机号规则:
- 以1开头
- 第二位3-9任意数字
- 三位以后任意数字9个
var reg = /^1[3-9][0-9]{9}$/;
console.log(reg.test("13345678909"));
元字符
.
:表示任意字符- 在正则表达式中使用\作为转义字符
\.
来表示.
\\
表示\
- \w:任意字母、数字、_
[A-z0-9_]
- \W:除了字母、数字、_
[^A-z0-9_]
- \d :任意的数字
- \D :除了数字
- \s :空格
- \S :除了空格
- \b :单词边界
- \B :除了单词边界
// 检查字符串是否有单词child
var reg = /\bchild\b/;
console.log(reg.test("hello child ren"))
// 去除开头的空格
// str = str.replace(/^\s*/,"");
// 去除结尾的空格
// str = str.replace(/\s*$/,"");
// 去除开头和结尾的空格
str = str.replace(/^\s*|\s*$/g,"");
console.log(str);
电子邮件规则
hello.nihao@abc.com.cn
任意字母数字下划线^\w{3,}
.任意字母数字下划线(可有可无)(\.\w+)*
@@
任意字母数字[A-z0-9]+
.任意字母(2-5位)(\.[A-z]{2,5}){1,2}$