js是编程语言,html是标记语言。
编程:就是让计算机为解决某个问题而是用某种程序设计语言编写程序代码,并得到最终结果的过程。
计算机语言:人与计算机之间的通讯语言,可以分为机器语言、汇编语言和高级语言,计算机最后执行的是机器语言,是由0和1组成的二进制数,二进制数是计算机语言的基础。
如今通用的编程语言有两种形式:汇编语言、高级语言(c++,java,pyson...)。
一、JavaScript简介
JavaScript: 基于对象和事件驱动,运行在浏览器客户端的脚本语言(Script意思脚本的),也是高级编程语言。
- 脚本语言:不需要编译,运行过程中由JS引擎逐行来解释并执行。
- HTML是网页的结构,CSS是网页的外观,而JavaScript是页面的行为。
- HTML页面是静态的(只供浏览),平常我们所见到的各种网页特效就是使用JavaScript实现的。
1.JS的作用
验证表单数据、轮播图、动态改变网页内容、动态改变网页外观、网页特效、响应事件。
2.浏览器执行JS
浏览器分为两部分:渲染引擎、JS引擎
- 渲染引擎:用来解析HTML、CSS,所称内核,比如chrome浏览器的blink。
- JS引擎:也叫JS解析器,用来读取网页中的JS代码,将其处理成二进制的机器语言,然后计算机去执行。
浏览器本身并不会去执行JS代码,是通过内置的JS引擎来执行JS代码,JS引擎执行代码时逐行解释每一句源码(转换为二进制机器语言),然后计算机去执行,所以JS语言被归为脚本语言,会逐行解释执行。
3.JS组成
- ECMAScript规定了JS的编程语法和基础核心知识,是所有浏览器运行商共同遵守的一套JS语法工业标准。
- DOM:文档对象模型,一套操作页面元素的API(大小、位置、颜色)。
4.JS的使用
JS代码有三个书写位置:行内式、内嵌式、外链式。
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
<!-- 2.内嵌式 -->
<script>
alert('aaaa')
</script>
<!-- 3.外链式 -->
<script src="1.js"></script>
</head>
<body>
<!-- 1.行内式 -->
<button onclick="alert('llll')">按钮</button>
</body>
</html>
5.JS的注释
- 单行注释
<script>//单行注释 ctrl+/</script>
- 多行注释
<script>/* 多行注释 alt+shift+a */</script>
6.JS的输入输出
<script>
alert('llllllll')//提示框
document.write('<h1>啦啦啦</h1>')//在网页中输出信息
//prompt取过来的值是字符型
prompt("这是个输入框","输入文字")//接受用户输入的输入框
confirm('确定吗')//确认框
console.log("日志"); //在控制台中输出消息
</script>
二、JS基础语法
1.字面量
在源代码中一个固定值的表示法,通过看具体的值,就能够知道数据类型。
- 数值字面量:8, 9, 10
var num = 2;
- 字符串字面量:'程序员', "大前端"
var num = "123";
2.变量
2.1什么是变量
变量:变量指的是在程序中保存数据的一个容器,变量的本质是程序在内存中申请的一块用来存放数据的空间。
2.2变量的使用
- 声明变量:利用var关键字声明变量
var 变量名;
- 赋值
变量名 = 值;
- 变量的初始化:声明变量并给值
var 变量名 = 值;
2.3声明变量的特殊情况
- 只声明不赋值,结果是undefined
var a;
console.log(a);//undefined
- 不声明不赋值,会报错
console.log(b);
- 不声明直接赋值,JS中允许使用
a=10;
console.log(a)//10
2.4变量的命名规范
- 由字母(A-Za-z)、数字(0-9)、下划线(_)、美元符号( $ )组成,如:var usrAge, num01, _name。
- 区分大小写 强调:JS 严格区分大小写 ,var app; 和 var App; 是两个变量。
- 不能以数字开头,或者汉字定义变量名。
- 不能是关键字、保留字和代码符号,例如:var、for、while、&, class。
- 不能出现空格,规范建议遵守的,不遵守的话JS引擎也不会报错。
- 变量名必须有意义。
- 遵守驼峰命名法,首字母小写,后面单词的首字母需要大写。
3.数据类型
数据类型分为简单数据类型和复杂数据类型。
- JS变量的数据类型是只有程序在运行过程中,根据等号右边的值确定的。
- JS是动态语言,变量的数据类型可以改变。
3.1简单数据类型
- 值类型∶简单数据类型/基本数据类型,在存储时变量中存储的是值本身,因此叫做值类型
<script>
//判断字符串类型只需看是否有引号
var a1=123; //number
var a2="123"; //string
var a3=true; //布尔
var a4="false";//string
var a5="1.63";//string
var a6="null"//string
var a7;//undefiend
//数字型最大值
console.log(Number.MAX_VALUE);
//数字型最小值
console.log(-Number.MAX_VALUE);
//无穷大Infinity
console.log(Number.MAX_VALUE*3);
//无穷小-Infinity
console.log(-Number.MAX_VALUE*3);
</script>
- 数值型(Number)
1.isNAN()这个方法用来判断变量是否为非数字类型,并返回一个值,如果是数字返回false,如如果非数字返回true。
<script>
console.log("lallalal"-100);//NaN
console.log(isNaN(12));//false
console.log(isNaN('lla'));//true
</script>
- 字符串型(String)
1.字符串可以是引号中的任意文本。可以使用单引号或双引号,因为HTML中使用的是双引号,所以推荐使用单引号。
2.单引号和双引号之间的嵌套遵循“外双内单”或者“外单内双”。
3.转义字符“\”: \n 换行 \\ 斜杠 \' 单引号 \" 双引号 \r 回车符
4.检测获取字符串长度
<script>
var a="xiao yan si qi"
console.log(a.length);//14 空格也算
</script>
5.字符串的拼接
字符串拼接 +; 只要有字符串和其他类型拼接,最终结果一定是字符串类型。
- 布尔型(Boolean)
- undefined型(Undefined)
变量声明但未赋值就是Undefined,未定义数据类型。
<script>
var c;
console.log(c);//undefined
console.log(c+1);//undefined与数字相加最后的类型是NaN
var d=undefined;
console.log(d+'啦啦啦啦');//undefined啦啦啦啦
</script>
- null型(Null)
<script>
var d=null;
console.log(d+'啦啦啦');//null啦啦啦
console.log(d+1005);//1005
</script>
注意:简单数据类型null返回的是一个空的对象object
如果有个变量我们以后打算存储为对象,暂时没想好放什么,这个时候就给null。
var a=null;
console.log(typeof a);//object
3.2复杂数据类型
- 通过new关键字创建的对象(系统对象、自定义对象),如Object、Array、Date等
object、array、symbol、function
4.typeof数据类型判断
1.可以通过控制台输出的颜色判断:数值型的是蓝色,字符型的是黑色,布尔型的是深蓝色,undefined和null是灰色。
2.使用 typeof操作符可以得到对应变量的数据类型。
<script>
console.log(typeof 12);//number
console.log(typeof 'lll');//string
console.log(typeof true);//bollean
console.log(typeof undefined);//undefined
console.log(typeof null);//object
</script>
5.数据类型转换
使用表单、prompt获取过来的数据默认是字符串类型的,此时就不能直接简单的进行加法运算,而需要转换变量的数据类型。通俗来说,就是把一种数据类型的变量转换成另外一种数据类型。
5.1转换成数值Number类型
- 法一:Number()函数
<script>
console.log(Number('1.2'));//1.2
console.log(Number('1111a'));//NaN
console.log(Number(''));//0
console.log(Number(true));//1
console.log(Number(false));//0
console.log(Number(null));//0
console.log(Number(undefined));//NaN
</script>
- 法二:parseInt(变量)取整
<script>
console.log(parseInt('123.456'));//123
console.log(parseInt('.123.456'));//NaN
console.log(parseInt('120px'));//120
console.log(parseInt('rem120px'));//NaN
</script>
- 法三:parseFloat取浮点数
<script>
console.log(parseFloat('123.456'));//123.456
console.log(parseFloat('a123.456'));//NaN number
console.log(parseFloat('.123.456'),typeof(parseFloat('.123.456')));//NaN number
console.log(parseFloat('120px'));//120
</script>
- 法四:隐式转换
利用算数运算“-、 *、 / ”都会转换成Number。
<script>
console.log('12'-0,typeof('12'-0));
console.log('1991'-'1005');//986
console.log('111'*1);
</script>
5.2转字符串String类型
- 法一:toString()
注意:null和undefined没有toString()方法,如果它们调用方法,会报错。
<script>
var num=1991;
var num1=null
var str=num.toString()
console.log(str,typeof str);//1991 string
console.log(num1.toString);//报错
</script>
- 法二:String()
注意:null和undefined调用String()函数,会将null直接转换为 “null”,将 undefined直接转换为 “undefined”。
<script>
var num=1991;
var num1=null
var str=String(num)
console.log(str,typeof str);//1991 string
console.log(String(num1));//null
</script>
- 法三:利用 + 拼接字符串
<script>
var num=1991;
console.log(num + '');
</script>
5.3转换为Boolean布尔类型
-
Boolean(变量)
0 、''(空字符串) 、 null、undefined、NaN会转换成false,其它都会转换true。
<script>
console.log(Boolean(''));// false
console.log(Boolean(0));//false
console.log(Boolean(NaN));//false
console.log(Boolean(null));//false
console.log(Boolean(undefined));//false
console.log(Boolean(111));//true
</script>
5.4案例
让用户输⼊⼀个三位数【整数】,使⽤代码分别获取到这个三位数字百位,⼗位,个位上的数字,例如:用户输⼊: 456, 最后在浏览中分别弹出 4,5,6
<script>
// 总数
var num =prompt("请输入三位数")-0;
// 百位
var bai = parseInt(num / 100);
alert('百位数是'+bai);
// 十位
var shi = parseInt((num - bai * 100) / 10);
alert('十位数是'+shi);
//个位
var ge = parseInt(num - bai * 100 - shi * 10);
alert('个位数是'+ge);
</script>
6.运算符
6.1算数运算符
- + 加法运算
如果+两边都是数字就是数学上的加,如果两边有字符串出现就会执行字符串的连接。
<script>
console.log('11'+11);'1111'
console.log(11+11);22
</script>
- - 减法运算
1. 如果是数值类型的变量相减,结果就是⼀个数值类型的结果。
2. 如果是数字的字符串相减,得到的结果也是⼀个数值类型结果(发生了隐式类型转化)。
3. 如果是非数字的字符串相减,得到的结果是NaN。
<script>
console.log('21'-11);//10
console.log(21-11);//10
console.log('a'-11);//NaN
//浮点数 会把小数转换成二进制数
console.log(0.1+0.2);//0.30000000000000004
var num=0.1+0.2;
//不要直接用浮点数进行比较
console.log(num == 0.3);//false
</script>
- * 乘法运算
-
/ 除法运算
1.如果是数值类型的变量相除,结果就是⼀个数值类型的结果。
2. 如果是数字的字符串相除,得到的结果也是⼀个数值类型结果(发⽣了隐式类型转化)
3. 如果是非数字的字符串相除,得到的结果是NaN。
4. 如果除数是0,得到的结果是 Infinity (无穷大的值)。
<script>
console.log(6/3);//2
console.log('6'/3);//2
console.log('6'/'a');//NaN
console.log('6'/0);//Infinity
</script>
- % 取余(获取余数)
<script>
console.log(0 % 0);//NaN
console.log(6 % 0);//NaN
console.log(6 % 4);//2
</script>
6.2赋值运算符
var a += b;等价于 a = a+b,以此类推。
<script>
var a = 9;
var b = 3;
b *= a;
console.log(b);//27
b /= a;
console.log(b);//3
</script>
6.3一元运算符
- ++(自增)
++a先加后用,a++先用后加。
<script>
var a = 1; var b = ++a + ++a; console.log(b); //2+3=5
var a = 1; var b = a++ + ++a; console.log(b); //1+3=4
var a = 1; var b = a++ + a++; console.log(b); //1+2=3
var a = 1; var b = ++a + a++; console.log(b); //2+2=4
</script>
- --(自减)
--a先减后用,a--先用后减。
6.4关系运算符
通过比较运算符得到的结果只有布尔类型true和 false。
<script>
console.log(100 < 100);//f
console.log(100 > 100);//f
console.log(100 >= 100);//t
console.log(100 <= 100);//t
console.log(100 == 100);//t
</script>
- === 用来判断值和数据类型必须同时相等
<script>
console.log(100 === 100);//t
console.log(100 === '100');//f
console.log(100 !== '100');//t
</script>
6.5逻辑运算符(与或非)
- && 与
要求所有的条件都必须满足才可以,即 一假为假,全真为真。
<script>
console.log(true && false);//f
console.log(true && true);//t
console.log(false && true);//f
</script>
- || 或
条件只要有一个满足即可,即全假为假,一真为真。
<script>
console.log(true || false);//t
console.log(true || true);//t
console.log(false || true);//t
console.log(false || false);//f
</script>
-
!非
取反。
<script>
console.log(!true);//f
console.log(!false);//t
</script>
6.6运算符优先级(了解)
小括号优先,赋值运算符最后。
优先级从高到底:
- () 优先级最高
- 一元运算符 ++ -- !
- 算数运算符 先* / % 后 + -
- 关系运算符 > 、>= 、< 、<=
- 相等运算符 ==、 !=、 === 、!==
- 逻辑运算符 先 && 后 ||
- 赋值运算符 =
6.7短路运算
如果在第一个位置就预判了结果,那就不向后执行。
- 或||:若第一个值为真则第一个值代整个表达式的值,不用再向后执行。
- 与&&:若第一个值为假则第一个值代整个表达式的值,不用再向后执行。
<script>
console.log(0 || alert('1005'));//弹
console.log(1 || alert('1005'));//不弹
console.log(1 || 0)//1
console.log(1 && 0)//0
console.log(alert('111') && 0)//弹 f
console.log(false && 1)//flase
console.log(true && 1)//1
console.log(1 && true)//true
console.log(0 || false)//flase
console.log(1 || true)//1
console.log(1 && 3)//3
console.log(0 || 5)//5
</script>
7.流程控制
流程控制就是控制我们的代码按照什么样的结构顺序来执行,有顺序结构,分支结构,循环结构。
- 值确定的时候适用swich值范围较大时适用if。
- switch效率高,if else if有几种条件就执行几次效率低。
7.1if语句
1.单分支:if (条件判断) {语句块}:条件判断(true)==>语句块,【如果为false,不执行】。
2.双分支:if (条件判断) {语句块}else{语句块}==>条件(true)==>if后面的语句块,只要条件(false)都执行else语句块。
3.多分支:if(条件判断){语句块}else if (条件判断) {语句块}else if (条件判断) {语句块}......else{语句块}。
案例:
- 分数转换,百分制转换成ABCDE: <60 E、 60-70 D 、70-80 C、 80-90 B 、90 -100 A。
<script>
var a = prompt('数字');
if (a >= 90) {
alert("A");
}
else if (a >= 80) {
alert("B");
}
else if (a >= 70) {
alert("c");
}
else if (a >= 60) {
alert("D");
}
else {
alert("E");
}
</script>
-
判断⼀个年份是闰年还是平年(闰年:能被4整除,但不能被100整除,或者能被400整除)。
<script>
var a=prompt("年份");
if((a % 4 == 0 && a % 100 != 0)|| a % 400 == 0){
alert('是闰年');
}
else{
alert('是平年');
}
</script>
- 依据⼀个人的年龄判断是否成年(大于18岁)
<script>
var year=prompt("出生年份") - 0;
if(2021-year>=18){
alert('已成年');
}
else{
alert('未成年');
}
</script>
- ⼀个加油站为了⿎励⻋主多加油,所以加的多有优惠。92号汽油,每升6元;如果⼤于20升,那么超出部分每升5.9;95号汽油,每升7元;如果⼤于30升,那么超出部分每升6.95,编写JS程序,用户输⼊自己的汽油编号,然后输入自己加多少升,弹出价格。
<script>
var a=prompt("92号汽油还是95号汽油")-0;
var b=prompt("加多少")-0;
var sum;
if(a==92){
if(b>20){
sum=(b-20)*5.9+20*6;
alert('总价格是'+sum);
}
else{
sum=b*6;
alert('总价格是'+sum);
}
}
else{
if(b>30){
sum=(b-30)*6.95+30*7;
alert('总价格是'+sum);
}
else{
sum=b*7;
alert('总价格是'+sum);
}
}
</script>
-
收先接收用户输⼊的用户名,判断该⽤户名是否是admin,如果不是直接程序终止,如果是那么再次提示让用户输⼊密码,如果密码是88888,那么提示登录成功,否则提示登录失败。
<script>
var name=prompt("输入用户名");
if(name =='admin'){
var pass=prompt("输入密码");
if(pass==='88888'){
alert('登陆成功');
}
else{
alert('登陆失败');
}
}
else{
alert('账号或密码错误');
}
</script>
7.2三元运算
表达式 ? 结果1 : 结果2
- 当点击确定,弹出消息提示“您已退出” 当点击取消 弹出消息“您已取消退出。
<script>
confirm('是否要退出') ? alert('已退出') : alert('失败')
</script>
-
接收用户输入的数字,判断是奇数还是偶数。
<script>
var a = prompt('数字');
a % 2 ==0 ? alert('偶数') : alert('奇数')
</script>
7.3switch语句
switch转换开关的意思 case 小例子或者选项的意思。
- 如果程序中表示的是一个具体的值, 可以用switch语句。
- 如果在程序中要表示一个范围,那么推荐使用条件判断。
- switch判断等不等用的是全等判断的 ===,switch 后面的变量数据类型必须和 case 后面的值数据类型保持一至。
- break语句必须加。
语法:
switch ( 变量 ) {
case 值1:
代码语句..
break;
case 值2:
代码语句...
break;
.......
default:
代码语句...
break;
}
- 分数分级
<script>
var num=prompt("分数是")-0;
num = parseInt( num/10 );
switch(num){
case 10:
case 9:
alert('A');
break;
case 8:
alert('B');
break;
case 7:
alert('C');
break;
case 6:
alert('D');
break;
default:
alert('不及格');
}
</script>
- 根据month的数值,输出对应月份的天数,2月默认28天。
<script>
var month = prompt('请输入月份')-0;
switch (month) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
console.log("31天");
break;
case 4:
case 6:
case 9:
case 11:
console.log("30天");
break;
case 2:
console.log("28天");
break;
default:
console.log("输入错误");
}
</script>
7.4循环
循环的目的:当我们要重复性的做同一件事的时候,本质就是重复执行同一段代码的时候。
三要素:变量初始化【var i = 1】,循环条件判断【i <= 100】,循环变量的改变【 i++;】。
- while循环与do while循环
while是先判断条件再执行;do while是先执行一次再判断条件。
1.while(条件表达式) { 代码(循环体) }
2.do { 循环体代码 }while(条件表达式)
- 打印人的一生从1到100岁
<script>
//while
var age=1;
while(age<=100){
document.write("<div>");
document.write(age);
document.write("</div>");
age++;
}
//do while
var age=1
do{
document.write('<div>')
document.write(age)
document.write('</div>')
age++
}while(age<=10)
</script>
- for循环
一般明确循环的次数for,循环次数不明确while。
for (变量初始化; 条件表达式 ; 变量自增(变量自减)) { 循环体代码 }
- 1-100的和5050
var sum=0;
for(var a=0;a<=100;a++){
sum+=a
}
console.log(sum);
-
在页面中打印两行10颗 *
for(var i=1;i<=2;i++){
for(var j=1;j<=10;j++){
document.write('*')
}
document.write('<br>')
}
- 打印直角三角形
for(var i=1;i<=9;i++){
for(var j=1;j<=i;j++){
document.write('*')
}
document.write('<br>')
}
- 打印99乘法表
for(var h=1;h<=9;h++){
document.write('<div class="box">')
for(var j=1;j<=h;j++){
document.write('<span>' + j + "*" + h +"=" + h*j+ '</span>');
}
document.write('</div>')
}
7.5continue与break
- continue是跳出本次循环进行下一次循环。
// 打印1-100之间的数,但不打印三的倍数
for(i=1;i<100;i++){
if(i%3==0){
continue
}
console.log(i);
}
- break是退出整个循环。
for(var i=1;i<=10;i++){
if(i==7){
break;
}
document.write("今天是" + i + "号")
document.write('</br>')
}
三、数组
1.创建数组
数组(Array)就是一组数据的结合,存储在单个变量下的优雅方式。
//1.利用数组字面量创建数组
var a1=[];//空数组
var a2=[1991,"sean",true,null,undefined,[]];
console.log(a2)
console.log(a2[1])
//2.利用new Array()
var arr=new Array(2)//这个2代表数组的长度为2,里面有两个空的数组元素
console.log(arr);//[空 ã2]
var arr1=new Array(2,3)//写两个以上的值,代表数组元素
console.log(arr);//[2,3]
2.访问数组元素
若想获取数组里面的某一个值,需要用下标(索引值)。
注意:数组的索引从0开始。
- 取值:数组[下标]
- 赋值:数组[下标] = 值;
3.遍历数组元素
利用for循环遍历数组元素
var a=[1991,"sean",true,null,undefined,[]];
for(i=0;i<a.length;i++){
console.log(a[i]);
}
-
给⼀个不重复的数字数组,求最大值和最大值的在数组中的位置。
var arr = [1, 2, 4232434, 6, 7, 8, 998]
var max = arr[0]
var position=0
for (var i = 0; i < arr.length; i++) {
if (arr[i] > max) {
max = arr[i]
position=i
}
}
console.log(max,position);
4.数组的长度
- arr.length
var a=[1,1,1,12,3,4];
console.log(a)
//数组的长度
console.log(a.length)
//数组的最后一个值的位置为数组长度-1
console.log(a[a.length-1])
5.案例:存钱取钱
var sum = 1005;
var b = true;
while (b) {
var a = prompt("请选择操作:\n 1.存钱 \n 2.取钱 \n 3.显示余额 \n 4.退出");
switch (a) {
case "1":
alert('存钱');
var num1 = prompt("存入的金额为") - '0';
sum += num1;
alert("余额为" + sum);
break;
case "2":
alert('取钱');
var num2 = prompt("取出的金额为") - '0';
sum -= num2;
alert("余额为" + sum);
break;
case "3":
alert('显示余额');
alert("余额为" + sum);
break;
case "4":
alert('退出');
b = false;
break;
}
}
6.二维数组
var a=[
[1,2,3,4,5],
[55,66,77],
[35,36,39]
]
console.log(a[1]);
console.log(a[0][4])
6.1遍历二维数组
var a = [
[1, 2, 3, 4, 5],
[55, 66, 77],
[35, 36, 39]
]
for (var i = 0; i <a.length; i++) {
for (var j = 0; j < a[i].length; j++) {
console.log(a[i][j]);
}
}
7.冒泡排序
是一种算法,把一系列数据按照一定的顺序进行排列显示(从大到小,或从小到大)。
//将数据从小到大排序
var a = [5, 7, 3, 8, 1, 9, 2, 6, 4];
var c;
//趟数
for (var j = 0; j <= a.length - 1; j++) {
//交换次数
for (var i = 0; i < a.length - 1 - j; i++) {
if (a[i] > a[i + 1]) {
c = a[i];
a[i] = a[i + 1];
a[i + 1] = c;
}
}
}
console.log(a);
8.检测是否为数组
- instanceof运算符,检测是否为数组
var arr=[];
var obj={};
console.log(arr instanceof Array);//true
console.log(obj instanceof Array);//flase
- Array.isArray(arr)
console.log(Array.isArray(12345));//false
console.log(Array.isArray([0,1]));//true
四、函数
函数:可以封装一段特定功能代码,然后通过函数名调用,实现对该段代码重复使用。
函数的使用分为两步:声明函数、调用函数。
1.创建函数
- 法一:利用函数关键字function自定义函数(函数声明)
function 函数名 (形参) {代码体}
调用函数:函数名()
function fn(){
alert(1)
}
fn()
- 法二:函数表达式(字面量)
把一个匿名函数:没有函数名的函数,保存到一个变量里面。
注意:匿名函数不能单独使用,可以将匿名函数赋值给⼀个变量,也可以让匿名函数自调用。
var a=function(){
alert(1)
}
a()
- 法三:构造函数
var fn=new Function(‘参数1’,’参数2’,’函数体’)
例:求给定范围内的数字和
function sum(a,b){
var sum=0
for(var i=a;i<=b;i++){
sum+=i
}
console.log(sum);
}
sum(1,100)
2.函数的参数
- 形参:形式上的参数,是给实参占地方的,接收实参,相当于一个变量但不予声明,写在声明函数的括号里。
- 实参:实际参与运算的数,写在调用函数的括号里。
注意:
-
如果实参的个数多于形参的个数,那么取到的是形参的个数。
function fn(a, b) {
alert(a + b);
}
fn(1, 2, 3);//3
-
如果实参的个数少于形参的个数,那么多余的形参定义成undefiend。
function fn(a, b) {
alert(a + b);
}
fn(1);//b是undefined,任何数与undefined相加都是NAN
- 例:求圆的面积
//Math.PI圆周率
function s(r){
alert(Math.PI * r * r);
}
s(1);
3.函数的返回值return
返回值:函数执行完后,可以把执行的结果通过return语法返回给调用者,函数只是实现某种功能,最终的结果需要函数将值返回给调用者。
注意(重点):
- 1. 如果函数没有显示的使用 return语句 ,那么函数有默认的返回值:undefined。
- 2. 如果函数中写了return语句,后面没有写任何其他内容,那么函数的返回值依然是 undefined。
- 3. 一个函数只能有一个返回值。
- 4. return 代码执行完成后,后面的代码不再执行。
- 5. 函数也可以作为返回值(理解)。
4.伪数组
伪数组并不是真正意义上的数组。
- 1.具有数组的length属性。
- 2.按照索引的方式进行存储
- 3.没有真正数组的一些方法,比如pop,push。
5.arguments
注意:只有函数才有arguments对象,而且是每个函数都内置好了arguments。
当我们不确定有多少个参数传递的时候,可以用arguments来获取。在JavaScript中,arguments实际上它是当前函数的一个内置对象。所有函数都内置了一个arguments对象,arguments对象中存储了传递的所有实参。
function fn(){
console.log(arguments);//里面存储了所有传递过来的实参,以伪数组的形式进行存储
console.log(arguments.length);
//可以按数组的方式遍历arguments
for(var i=0;i<arguments.length;i++){
console.log(arguments[i]);
}
}
fn(1,2,3,4,)
fn(6,1,3,4,5,6,7)
- 例:判断任意个数的最大值
function fn(){
var max=arguments[0]
for(var i=0;i<arguments.length;i++){
if(arguments[i]>max){
max=arguments[i]
}
}
console.log(max);
}
fn(1,2,3,4,5,7)
- 例:写⼀个函数,实现对数字数组的排序。(冒泡排序)
function fn() {
for (var j = 0; j < arguments.length; j++) {
for (var i = 0; i < arguments.length - 1 - j; i++) {
if (arguments[i] > arguments[i + 1]) {
var c;
c = arguments[i];
arguments[i] = arguments[i + 1];
arguments[i + 1] = c;
}
}
}
console.log(arguments);
}
fn(5,2,4,7,89,0)
6.函数的相互调用
function a(){
console.log('a');
b()
}
a()
function b(){
console.log('b');
}
- 例:判断二月份有几天,闰年29天,平年28天
function a(){
var year=prompt("输入年份");
if(b(year)){
alert(year + "的二月份有29天");
}
else{
alert(year + "的二月份有28天");
}
}
a();
function b(year){
var arr=false;
if(year%4==0 && year%100!=0 || year%400==0){
arr=true;
}
return arr;
}
//法二
function fn(){
var year=prompt("请输入年份")
f1(year)
}
fn()
function f1(year){
if(year%4==0||year%100!=0&&year%100==0){
alert('2月有29天')
}
else{
alert('2月有28天')
}
}
五、JS的作用域
作用域: 变量或者函数可以起作用的区域,目的是提高程序的可靠性,减少命名冲突。
JS的作用域分为全局作用域、局部作用域、块级作用域(目前学习的是es5,没有,es6有)。
1.全局作用域
- 在全局作用域中有一个全局对象window,它代表的是一个浏览器的窗口,它由浏览器创建,我们可以直接使用。
- 在函数外部叫做全局作用域,全局变量:在整个script标签中或者js文件中定义的变量,在任何地方都可以访问。
var num=100;
2.局部作用域(函数作用域)
- 在函数内部就是局部作用域,局部变量:在函数内部定义的变量,只能在定义变量的函数中使用。
function fn(){
//局部作用域
}
var a=100;
console.log(a);
function fn(){
var num=200
console.log(num);
}
fn()
3.全局变量
- 全局作用域下的变量叫做全局变量,在全局下都可以使用。
- 注意:如果在函数内部未声明但直接赋值的变量也是全局变量。
var a=100;//a就全局变量
console.log(a);//100
function fn(){
console.log(a);//100
}
fn()
4.局部变量
- 局部作用域下的变量叫做局部变量,或者在函数内部的变量叫局部变量,只能在函数内部使用。
- 注意:其中函数中所传递的参数也是局部变量(小括号中的)。
function fn(){
var num=1
}
fn()
console.log(num);//num is not defined
</script>
从执行效率来看全局变量和局部变量:
- 全局变量只有浏览器关闭的时候才会销毁,比较占内存资源。
- 局部变量当我们程序执行完毕就会销毁,比较节约内存资源。
5.作用域链
- 根据内部作用域可以访问外部作用域的机制,当访问一个变量时,会先从本作用域中去找这个变量,若找不到则向上一级作用域中去找,依次类推,就形成了一个作用域链。
-
(优先查找局部的,就近原则)没有的话就向上找值,直到有值为止。
-
全局不能使用局部的。
function f1(){
var num = 123;
function f2(){
console.log(num);
}
f2();
}
var num=456;
f1(); //123
//0级链:var num=456; f1()
//1级链:var num = 123; f2()
//2级链:console.log(num);
六、预解析
JavaScript代码是由浏览器中的JavaScript解析器来执行的。JavaScript解析器在运行JavaScript代码的时候分为两步(先阅读代码):
- 预解析:js引擎会把js代码中所有的var、function提到当前作用域的最前边。
- 代码执行:是按照代码的书写顺序从上往下依次执行。
1.变量预解析(变量提升)
- 把所有变量声明提升到当前作用域的最前边,不提升赋值操作。
console.log(num);
var num=1005;//undefined
//预解析:var num;
// console.log(num);
// num=1005;
2.函数预解析(函数提升)
- 把所有函数声明提升到当前作用域的最前边,不调用函数。
fun();
var fun=function(){
console.log(2001);
}
//函数表达式:调用必须写在函数表达式的下边
//预解析:var fun;1.
// fun();2. 2--->1声明变量但没给值也没给函数 错fun is not a function
// fun=function(){
// console.log(2001);
// }
- var a = b = c = 9;【var a=9;b=9;c=9】
f1();
console.log(c);
console.log(b);
console.log(a);
function f1() {
var a = b = c = 9;//【var a=9;b=9;c=9】
console.log(a);
console.log(b);
console.log(c);
}
//预解析
// function f1 () {
// var a ;
// a=9;
// b=9;
// c=9;
// console.log(a);
// console.log(b);
// console.log(c);
// }
// f1();
// console.log(c);
// console.log(b);
// console.log(a);//9 9 9 9 9 错误
3.优先函数
如果函数名和变量名一样,优先函数,函数的优先级更高。
console.log(a);
var a = 100
function a() {
console.log(100);
}
//结果是:
// function a(){
// console.log(100);
// }
//预解析
// var a
// function a(){
// console.log(100);
// }
// console.log(a);
// a=100//被方法a覆盖
七、对象
在JavaScript中,对象是一组无序的相关属性和方法的集合,所有的事物都是对象,例如字符串、数值、数组函数等。
- 属性:事物的特征。
- 方法:事物的行为,函数放在对象中叫方法。
- 可以让js结构更清晰。
1.创建对象
1.1字面量创建对象
var obj(对象名) = {}//创建一个空的对象:没有任何属性和方法的对象
var obj//(!这个是对象名)
= {
uname:'panda',
age: 3,
sex:'男',
height: 183.6,
sayhi: function (){
console.log('hi~');
}
}
console.log(obj.uname);//或者
console.log(obj['age']);
obj.sayhi();
调用对象的属性:对象名.属性名 或者 对象名['属性名']
调用对象的方法 对象名.属性名()
1.2通过构造函数Object创建对象
- Object是这门语言内置的一个构造函数,new在内存上开辟新的空间,创建一个对象,保存到了变量中。
- 构造函数,是一种特殊的函数(方法),与new一起使用,用于初始化(创建)对象。
- 为什么叫构造函数?因为其使用的方式不同,前边要加关键字new,加上new之后才能使用。
创建对象:var 变量 = new Object();
添加属性: 对象变量.属性名 = 值;
添加方法: 对象变量.方法名 = function () {}
var ojb = new Object();
ojb.uname = 'panda';
ojb.age = 18;
ojb.sayhi = function () {
console.log('hi~');
}
console.log(ojb.uname);
console.log(ojb['age']);
ojb.sayhi();
1.3 通过自定义构造函数创建
因为我们一次创建一个对象,里面很多的属性和方法是大量相同的我们只能复制,所以我们可以利用函数的方法,重复这些相同的代码,我们就把这个函数称为构造函数,这个函数不一样,里面封装的不是普通代码,而是对象。
function 构造函数名(){
// this(当前的).属性 = 值;
// this.方法=function(){};
// }
new 构造函数名();
function wzry(uname,style,blood){
this.name=uname;
this.style=style;
this.blood=blood;
this.act=function(action){
console.log(action);
}
}
var lp=new wzry('廉颇','力量型',500);
console.log(lp.name);
console.log(lp.style);
console.log(lp.blood);
关键字new的执行过程:
- new 构造函数在内存中创建了一个新对象
- this指向刚才创建的空对象
- 执行构造函数里边的代码,给空对象添加属性和方法
- 返回对象(不需return)
2.变量、属性、函数、方法的区别
- 变量是单独声明并赋值,使用的时候直接写变量名,单独存在。
var num=10;
console.log(num);
- 属性在对象里不需要声明,使用的时候是对象.属性或者对象['属性']。
var obj={
age:18
}
console.log(obj.age);//或者
console.log(obj['age']);
- 函数是单独声明并调用:函数名(),单独存在的。
function a(){
}
a()
- 方法:对象里的函数称为方法,方法不需要声明,调用:对象名.方法()
var obj={
l:function(){
}
}
obj.l();
3.instanceOf关键字
instanceof 运算符用于检测构造函数的prototype属性是否出现在某个实例对象的原型链上。 判断对象是哪个构造函数创建的。
4.遍历对象for in
for(变量 in 对象){对象[变量]}
var ojb={
name:'11',
age:"22",
sex:"男",
k:'8888',
fn:function(){
}
}
//k代表键
for(var k in ojb){
console.log(k);//得到的是键
console.log(ojb[k]);//得到的是属性值 k是变量 不加引号
// console.log(ojb.k);8888 .后边的跟是字面量 代表键值是K的 没有的话默认是undefined
}
例:通过构造函数创建3个对象,并将3个对象放到数组中,最后再将数组中每一个对象的信息输出。备注:对象的基本属性有 name , gender , age,对象的信息需要从用户输入中获取。
function People(name, gender, age) {
this.name = name
this.gender = gender
this.age = age
}
var arr = []
for (var i = 0; i < 3; i++) {
var name = prompt('请输入名字')
var gender = prompt('请输入性别')
var age = prompt('请输入年龄')
arr[i] = new People(name, gender, age)
}
console.log(arr);
for (var i = 0; i < arr.length; i++) {
for (var k in arr[i]) {
console.log(k, arr[i][k]);
}
}
八、内置对象
内置对象就是指JS语言自带的一些对象,这些对象供开发者使用,并提供了一些常用的或是最基本而必要的功能(属性和方法)。
- JavaScript组成: ECMAScript | DOM | BOM
- ECMAScript: 变量 , 函数, 数据类型 ,流程控制,内置对象.....
- JS中的对象: 自定义对象 , 内置对象 , 浏览器对象(不属于ECMAScript)
- Math对象,Array对象,Date对象
- 通过查文档学习内置对象 MDN (https://developer.mozilla.org/zh-CN/docs/Web/JavaScript)
1.Math对象
Math数学射象不是一个构造函数﹐所以我们不需要new来调用,直接使用里面的属性和方法即可。
- Math.PI 获取圆周率【属性】
console.log(Math.PI);
- Math.max()【方法】 返回⼀组数中的最大值 (可以设置多个数值型参数,返回其中最大值,其余返回的是NAN)
console.log(Math.max(1,2,3,4));//4
console.log(Math.max([1,2,3,4]));//NaN
console.log(Math.max(1,2,'3'));//NaN
console.log(Math.max());//-Infinity
- Math.random() 返回[0,1)之间的随机数 [灵活使用]
//随机验证码
function sjyzm(){
var str=''
for(var i=0;i<6;i++){
var num=parseInt(Math.random()*10)
str+=num
}
return str
}
console.log(sjyzm());
- Math.ceil() 向上取整,返回⼀个大于当前数字的整数
// 求 1 到 10之间的随机整数[包括1和10]
function sjzs(){
var num=Math.ceil((Math.random()*10))
return num
}
console.log(sjzs());
- Math.floor() 向下取整,返回⼀个小于当前数字的整数
// 求 20 到 50之间的随机整数[包括20 和 50]
// 求 n 到 m之间的随机整数[包括n 和 m]
function sjzs() {
var num = Math.floor((Math.random() * (50 - 20 + 1)) + 20)
//var num = Math.floor((Math.random() * (m - n + 1)) + n)
return num
}
console.log(sjzs());
//随机生成RGB颜色 (0-255) 例:rgb(11,11,11)
var str = 'rgb('
function rgb() {
for (var i = 0; i < 3; i++) {
var num = Math.floor((Math.random() * (255 + 1)))
str += num
if(i==2){
continue
}
str +=','
}
str +=')'
return str
}
console.log(rgb());
- Math.abs() 取绝对值(返回当前数字的绝对值,正整数)
2.Date对象
Date()日期对象,是一个构造函数,必须使用new来调用创建我们的日期对象。
- 返回系统的时间
var a=new Date();
console.log(a);
- 返回指定的时间
var b=new Date('1991-9-28');//没指定时间 那默认是8点
console.log(b);
var c=new Date('1990-10-15 10:55:00');
console.log(c);
var time=new Date(2001,3,2,4,2,6);//这种形式下,月份从0开始,0代表1月
console.log(time);
2.1日期格式化
- 获取日期其他部分
- 写⼀个函数,格式化日期对象,返回 y-m-d H:mm:s 形式
function date(date) {
var y = fn(date.getFullYear());
var m = fn(date.getMonth() + 1);//getMonth()返回的月份从0开始
var d = fn(date.getDate());
var h = fn(date.getHours());
var mm = fn(date.getMinutes());
var s = fn(date.getSeconds());
return y + '-' + m + '-' + d + " " + h + ':' + mm + ':' + s;
}
console.log(date(new Date()));
function fn(num) {
return num < 10 ? '0' + num : num;
}
- 获取毫秒值
是距离1970.01.01的毫秒值
console.log(time.valueOf());//或者
console.log(time.getTime());
Date.now()当前系统时间距离1970.01.01的毫秒值
+new Date():最常用的写法
2.3日期计算
计算距离2022-10-01 9:10:36还有多少天多少小时多少分多少秒
function time(date){
//获取当前日期的毫秒值
var nowtime=+new Date()
//获取目标日期的毫秒值
var goaltime=+new Date(date)
//获取目标日期距离当前日期的毫秒值
var times=goaltime-nowtime
//格式转换
//天
var day = parseInt(times/1000/60/60/24)
day=day <10 ? '0' + day : day
//小时
var hours=parseInt(times/1000/60/60%24)
hours=hours <10 ? '0' + hours : hours
//分钟
var minutes=parseInt(times/1000/60%60)
minutes=minutes <10 ? '0' + minutes : minutes
//秒
var seconds=parseInt(times/1000%60)
seconds=seconds <10 ? '0' + seconds : seconds
return '距离'+date+'还剩'+day +'天'+hours+'小时'+minutes+'分'+seconds+'秒'
}
console.log(time('2022-4-28 9:10:21'));
3.数组对象
数组中常用的方法
3.1判断变量是不是一个数组
- Array.isArray(ary)
console.log(Array.isArray(12345));//false
console.log(Array.isArray([0,1]));//true
3.2添加删除数组元素的方法
- ary.push(元素) [常用] 在数组中末尾添加一个或多个值,返回的是新数组的长度,原数组会发生变化
var arr=[1,2,3]
console.log(arr.push('后边'));//4
console.log(arr);//[1, 2, 3, '后边']
- ary.unshift(元素) 在数组中最开始位置添加一个值,返回的是新数组的长度 ,原数组会发生变化
var arr=[1,2,3];
arr.unshift(4);
console.log(arr);[4,1,2,3]
- arr.pop() 删除数组中的最后一个元素,没有参数,返回的是被删除的元素,原数组发生变化
var arr=[1,2,3,'删除'];
console.log(arr.pop());//删除
console.log(arr);//[1, 2, 3]
- arr.shift()删除数组中的第一个元素,没有参数,返回的是被删除的元素,原数组发生变化
var arr=['删除',1,2,3];
console.log(arr.shift());//删除
console.log(arr);//[1, 2, 3]
3.3数组排序
- reverse()翻转
var arr=[1,2,3,4,5];
arr.reverse()
console.log(arr);//[5, 4, 3, 2, 1]
- sort()冒泡排序
var arr=[2,34,55,54];
arr.sort()
console.log(arr);//[2, 34, 54, 55]
注意:如果调用该方法时没有使用参数,将按字母顺序对数组中的元素进行排序,说得更精确点,是按照字符编码的顺序进行排序
var arr=[2,277,344,56,54];
arr.sort()
console.log(arr);//[2, 277, 344, 54, 56]
解决:
var arr = [2, 277, 344, 56, 54];
arr.sort(function (a, b) {
return a - b;//从小到大
// return b-a;//大小到小
});
console.log(arr);
3.4数组索引方法
- indexof(元素,[起始位置])
var arr = ["香蕉","苹果","苹果","西瓜"];
console.log(arr.indexOf("苹果"));//1
console.log(arr.indexOf("榴莲"));//-1
- lastIndexof(元素)
var arr = ["香蕉","苹果","苹果","西瓜"];
console.log(arr.lastIndexOf("西瓜"));//3
- 案例:!数组去重[ 'c', 'a', 'z' , 'a', 'x', 'a', 'x' , 'c', 'b']要求去除数组中重复的元素。
1.目标:把旧数组里面不重复的元素选取出来放到新数组中,重复的元素只保留一个,放到新数组中去重。
2.核心算法:我们遍历旧数组,然后拿着旧数组元素去查询新数组,如果该元素在新数组里面没有出现过,我们就添加,否则不添加。
3.我们怎么知道该元素没有存在?
利用新数组.indexOf(数组元素)如果返回时-1就说明新数组里面没有改元素
4.封装一个去重的函数unique独一无二的
function unique(arr){
var newArray=[]
for(var i=0;i<arr.length;i++){
if(newArray.indexOf(arr[i])=== -1){
newArray.push(arr[i])
}
}
return newArray;
}
var arr=unique([ 'c', 'a', 'z' , 'a', 'x', 'a', 'x' , 'c', 'b'])
console.log(arr);
3.5数组转换成字符串
- toString()
var arr = [1,2,3,4];
console.log(arr.toString());//1,2,3,4
- join(分隔符)
var arr = [1,2,3,4];
console.log(arr.join('$'));//1$2$3$4
3.6拼接数组
concat() :把两个数组拼接到一块,返回一个新数组,不修改原数组
var arr = [1,2,3,4];
var arr1=[9,7,6]
console.log(arr.concat(arr1));// [1, 2, 3, 4, 9, 7, 6]
console.log(arr);// [1, 2, 3, 4]
3.7截取数组
slice(startindex(下标), endindex(下标)):从当前数组中截取一个新的数组(包左不包右)
var arr = [1,2,3,4];
console.log(arr.slice(0,2));// [1, 2]包左不包右
console.log(arr);// [1, 2, 3, 4]
3.8修改、删除原数组
splice(startindex, deletCont, options):删除或者替换数组中的某些值,修改原数组
第一个参数代表从哪开始删除
第二个参数代表一共删除几个
第三个参数代表要替换的值
var arr = [1,2,3,4];
arr.splice(0, 2,'啦啦啦');
console.log(arr);//['啦啦啦', 3, 4]
4.字符串对象
字符串所有的方法,都不会修改字符串本身(字符串是不可变的),操作完成会返回一个新的字符串。
特性: 不可变性
注意:别大量替换字符串
4.1基本包装类型
4.2字符串不可变
4.3根据字符返index
- indexof(元素,[起始位置])
var str = '半岛铁盒,铁盒的序';
console.log(str.indexOf('半'));//0
console.log(str.indexOf('盒',4));//6
案例:'qweqweoeqweroqweqweodfsfdo',查找字符串中所有字母 'o'出现的位置
var str='qweqweoeqweroqweqweodfsfdo'
var index=str.indexOf('o')
while (index!==-1) {
console.log(index);
index=str.indexOf('o',index+1)
}
4.4根据位置返回字符
- charAt(index) :获取指定位置处的字符
var str='qweqweoeq'
for(var i=0;i<str.length;i++){
console.log(str.charAt(i));
}
- charCodeAt(index)返回相应索引号的字符ASCII值目的:判断用户按下了哪个键
var str='qweqweoeq'
console.log(str.charCodeAt(0));//113
- str[index] H5 新增的
var str='qweqweoeq'
console.log(str[0]);//q
案例:统计出现次数最多的字符
1.核心算法:利用 charAt()遍历这个字符串
2.把每个字符都存储给对象,如果对象没有该属性,就为1,如果存在了就+13.遍历对象,得到最大值和该字符
var str = 'qweqweoe'
var obj = {}
for (var i = 0; i < str.length; i++) {
var chars = str.charAt(i)//chars是字符串的每一个字符
if (obj[chars]) {
obj[chars]++
} else {
obj[chars] = 1
}
}
console.log(obj);//{q: 2, w: 2, e: 3, o: 1}
//遍历对象
var max = 0;
var ch = ''
for (var k in obj) {
//k是属性名
//obj[k]是属性值
if (obj[k] > max) {
max = obj[k];
ch = k;
}
}
console.log(ch, max);//e 3
4.5字符串操作方法
- substr((start,length) 截取字符串,从哪开始截几个
var b = '栀子花白花瓣'
console.log(b.substr(4,2));//花瓣
- replace(a,b) 用b替换a
var a='ABCDEabcdea';
console.log(a.replace('a','啦'));//默认 只替换一个a
console.log(a);//字符串不可变
console.log(a.replace(/a/g,'啦'));//全局替换 g:global 只替换小写字母
console.log(a);
console.log(a.replace(/a/gi,'啦'));//大小写全替换
console.log(a);
- split() 以一个分割符,将一个字符串串分割成一个数组
var b = '6,7,9,0';
console.log(b.split(','));//['6', '7', '9', '0']
var e = '6,7&9&0';
console.log(e.split('&'));//['6,7', '9', '0']
- 案例:获取url中 的⽤户名和密码 https://www.test.com/login?name=aa&pwd=123
var url = 'https://www.test.com/login?name=xz&pwd=123'
//方案(一):截取所需的字符
//获取'?'的下标
var index = url.indexOf('?')
//截取所需的字符
var strOjb = url.slice(index + 1)
// console.log(strOjb);//name=xz&pwd=123
//方案(二)
// console.log(url.split('?')[1]);
// 分割信息
var a = strOjb.split('&')
// console.log(a);//['name=aa', 'pwd=123']
//进一步处理信息
var nameArr = a[0].split('=')
var pwdArr = a[1].split('=')
// console.log(nameArr);// ['name', 'aa']
// console.log(pwdArr); //['pwd', '123']
var ojb = {
[nameArr[0]]: nameArr[1],
[pwdArr[0]]: pwdArr[1]
}
console.log(ojb);