JavaScript(2021.9.26)

一、引入

1.计算机语言JavaScript(2021.9.26)_第1张图片

JavaScript(2021.9.26)_第2张图片

JavaScript(2021.9.26)_第3张图片

2.编程语言和标记语言的区别

 3.数据存储单位

JavaScript(2021.9.26)_第4张图片

 二.JavaScript简介

1.JS参考文献

菜鸟教程:AngularJS 参考手册 | 菜鸟教程

W3school:JavaScript 参考手册

MDN:JavaScript 参考 - JavaScript | MDN

2.JS是什么?

JS的标准命名为ECMAScript,但实际上JavaScript的含义更大一些。JavaScript包括ECMAScript、DOM(文档对象模型,通过JS操作网页)、BOM(浏览器文档对象模型,通过JS操作浏览器)

 3.JS的作用

JS的出现主要用于处理网页中的前端验证(在浏览器中检查用户输入的内容是否符合一定的规则,如:用户名的长度,密码的长度,邮箱的格式

JavaScript(2021.9.26)_第5张图片

 4.浏览器执行JS的过程JavaScript(2021.9.26)_第6张图片

 5.JS的组成            (jsapi)

JavaScript(2021.9.26)_第7张图片

 ECMA 欧洲计算机联盟

Web APIs 包括 DOM(控制标签,对页面元素进行移动、大小、添加、删除等操作),BOM(操作浏览器,比如页面弹窗、检测窗口宽度、存储数据到浏览器)

6.JS三种书写位置

(1)行内(内联)样式,写在标签的属性中

点击按钮或超链接时,js代码才会执行


点击超链接
script可以写到标签内部

(2)内部(内嵌)样式,写在head的标签script中

(3)外部(外链)样式,head中连接,一个html文件可以连接多个js文件

注意:不要在标签中写代码,会不生效

7. Unicode编码

可查询Unicode编码对照表

JavaScript(2021.9.26)_第8张图片三、注释

1.//  单行注释(ctrl+/)

2./* */  多行注释(ctrl+shift+/ 或 shift+alt+A)

四、调试

断点调试

把 变量、表达式、条件判断 添加至监视表达式,然后刷新,一步一步执行(注意:点两次执行该语句或到下一句才执行)

第1个图标:跳过下一个函数调用,不进入函数内部;

第2个图标:进入下一个函数调用,会一步一步执行;

五、输入输出语句

1.输入语句

prompt();     输入框

prompt("请输入你的年龄");

2.输出语句

(1)alert();                    弹出警告框

(2)document.write();   向body中添加一个内容,可在页面中输出

//不仅可以输出文字,还可以解析输出标签
document.wwrite('

名字

')

(3)console.log();         向控制台输出一个内容,返回值是标签字符串

(4)console.dir();          返回的是键值对(对象)

(5)confirm();              确认框

注意

  • 结束符为英文分号,可写可不写 ;
  • document.write、console.log 输出多个变量用英文逗号隔开,alert 不能一次输出多个变量;

六.变量

1.变量的概念

变量就是一个容器,是内存里的一块空间,用于存储数据(为什么需要变量?)。方便以后使用里面的数据。

2.声明变量

let / var / const 都可以声明变量

  • let 不能多次声明同一个变量;var 可以重复声明,第二次声明会覆盖第一次声明的值;
  • let name = '比方'
    let name = '粉笔'
    此写法错误

 let / var / const 三者的区别:

  1. var属于window;let不属于window;
  2. var可重复定义赋值;let不可重复定义赋值;
  3. var定义的变量不具有块级作用域(即,在块级外也可使用);let定义的变量具有块级作用域;
  4. const定义的变量必须有初始化的值;const定义的变量不允许改值(重新赋值);把固定不变的值设置为常量;const定义的变量具有块级作用域

var a;        let b;        const c=123;

3.变量的初始化

声明变量 变量名=变量值;     例:var age=18;

声明的同时赋值称为变量的初始化

4.变量语法扩展

(1)更新变量

一个变量被重新赋值后,它原来的值就会被覆盖,变量值将以最后一次赋的值为准。

(2)同时声明多个变量

只需写一个var,多个变量名之间用英文逗号隔开

var name="旗木卡卡西",sex='女',age="30";

5.变量命名规范

JS中可以由自己命名的称为标识符。如,变量名,函数名,属性名

(1)由字母、数字、下划线(-)、美元符号($)组成(注:命名的单词间不能有空格);

(2)不能以数字开头;

(3)不能是关键字、保留字,(注:在有些浏览器中name是有含义的,所以尽量不用name,可以用myName);

(4)严格区分大小写。var age和var Age是两个变量;

(5)遵守驼峰命名法。首字母小写,后面单词的首字母大写(小驼峰),如,myFirstName

6.交换变量案例

1.交换变量
var a=1,b=3;
var t=a;   //t为临时变量
var a=b;
var b=t;
console.log(a,b);    //a=3,b=1
2.输入并弹出用户名
var a=prompt("请输入你的名字");
alert("欢迎"+a);

七、数据类型

根据数据所占空间不同,分成了不同的数据类型。(充分利用存储空间)

JS是一种弱类型语言,变量的数据类型是可以变化的。JavaScript(2021.9.26)_第9张图片

简单类型和复杂类型: 

  • 简单类型又叫做基本数据类型或者值类型,复杂类型又叫做引用类型;
  • 简单类型:string ,number,boolean,undefined,null ;
  • 复杂类型:通过 new 关键字创建的对象(系统对象、自定义对象),如 Object、Array、Date
  • 简单类型在存储时变量中存储的是值本身; 引用类型在存储时变量中存储的仅仅是地址;
  • 简单类型的数据直接存放在栈中;引用类型在栈里存放的是地址,真正的对象实例存放在堆中

1.number

(1)进制

JS进行浮点运算可能不精确,因为计算机是二进制

JavaScript(2021.9.26)_第10张图片

(2)特殊值

Number.MAX_VALUE  表示最大数值;

Number.MIN_VALUE  表示大于0的最小值;

Infinity  表示正无穷;

-Infinity  表示负无穷;

NaN  是一个特殊的数字,表示not a number;

(3)isNaN()  用来判断一个变量是否为非数字的类型

 2.string

使用表单、prompt 获取过来的数据默认是字符串类型的

(1)引号的使用(内双外单,外单内双)

1)用 '' (单引号) / ""(双引号) / ``(反引号) 包裹的都是字符串

2)在JS中字符串需要使用引号(双引号或单引号都可以,但不要混着用)引起来,不加引号会被认为成变量;

3)引号不能嵌套。双引号里不能放双引号,单引号里不能放单引号(就近原则),但双引号里能放单引号,单引号里能放双引号;

(2)转义符(都是以\开头的)

   \” 表示  双引号“

   \’ 表示  单引号 ’

  \n  表示  换行       注:要放在引号里使用 '\n'    反引号内不用加引号    \n只能console.log中起作用

  \t  表示  Tab键

 \b  表示   空格

  \\  表示  一个斜杠 \

  \\\\ 表示  两个斜杠 \\

(3)检测获取字符串长度(length )

var s="来庄里吧!";
console.log(s.length); /*length=5*/

(4)字符串的拼接

方法一:加号(+)

只要有字符串和其他类型相拼接,最终的结果是字符串类型(拼接前会把与字符串相加的任何类型转成字符串,再拼接成一个新的字符串)

console.log("河北"+"石家庄");  /* 河北石家庄 */
console.log("SHY"+24);      /* SHY24 */
console.log("12"+12);       /* 1212 */
console.log("河北"+true);    /* 河北true */

字符串和变量的拼接(因为变量可以很方便地修改里面的值)

var name="旗木卡卡西",age="25";
console.log('你好,我叫'+name+',今年'+age+'岁了!')
用户输入并反馈给用户
var age=prompt('请输入您的年龄:');
alert('您今年'+age+'岁啦!');

 方法二:模板字符串(反引号与${})

  • 模板字符串使拼接字符串更简便;
  • 用 反引号 包含数据,用 ${变量名} 来使用变量;
let name="旗木卡卡西",age="25";
document.write(`我是${name},今年${age}了!`)

3.boolean

布尔型有两个值:true(真)和false(假);

布尔型与数字型相加时,true的值为1,false的值为0;

console.log(true+3);   //1+3=4
console.log(false+3);  //0+3=3

4.null(空值)和undefined(未定义)

(1)null表示一个为空的对象;

         使用typeof检查一个null值时,会返回object;

(2)当声明一个变量,但不赋值时,它的值就是undefined;

         使用typeof检查一个undefined时,会返回undefined;

console.log(null+2);       //0+2=2
console.log(undefined+3);  //NaN
console.log(null+'SHY');       //null+SHY
console.log(undefined+'SHY');  //undefinedSHY

5.获取变量数据类型(typeof)

形式:typeof+变量名

注:null值返回的是object;prompt返回的是字符型(string).

var name="旗木卡卡西";  //string
var a=null;          //object
var b;               //unundefined 
document.write(typeof name,a,b);
var age=prompt('请输入您的年龄:');
document.write(typeof age);  //string

6.数据类型转换

(1)转换成字符串类型JavaScript(2021.9.26)_第11张图片

1)方式一  tostring()方法不会影响到原变量,它会将转换的结果返回,但null和undefined这两个值没有tostring()方法,如果调用他们的方法会报错。

num.toString()

// 数字17转成string类型

let A = (17).toString()

// 结果为 17,类型为 string

num.toString(进制数)

// 17转16进制

 let A = (17).toString(16)

// 结果为 11,类型为 string

2)方式二  调用  string(数据)  函数,并将被转换的数据作为参数传递给函数;使用string()函数做强制类型转换时,对null和undefined及其它所有类型都起作用(将null转换为”null”   将undefined转换为” undefined”)。

3)方式三  隐式转换的形式:变量+' '       如,alert(unm+' ');

(2)转换成数值型

JavaScript(2021.9.26)_第12张图片

1)parseInt()可以将一个以数字开头的字符串中的有效的整数(遇到出数字以外的内容就结束)内容取出来

如:123.45px经ParseInt()转换成123

12a3.45px经ParseInt()转换成12

123px456经ParseInt()转换成123

abc12.35经ParseInt()转换成NaN

true 经ParseInt()转换成 NaN

false 经ParseInt()转换成 NaN

'null' 经ParseInt()转换成 NaN

null 经ParseInt()转换成 0

2)parseFloat()可以获得以数字开头的非纯数字字符串中有效的小数

如:123.456px经ParseInt()转换成123.456

    123.456.789px经ParseInt()转换成123.456

 3)number()函数

JavaScript(2021.9.26)_第13张图片

JavaScript(2021.9.26)_第14张图片

4)隐式转换(- * /)

+数据 +作为正号,其他数据类型可以转为数字类型(input和prompt输入的都是字符串类型)
let A = +prompt('输入工资')    // A为数字类型

+的作用:连接符、运算符、正号

将字符型12转换成数值型12,再进行运算

console.log('12'-0)  //12
console.log('123'-'120')   //3
console.log('12'*1)  //12
console.log('12'/1)  //12

5)三个案例

1.计算年龄案例
var year=prompt('请输入您的出生年份:');
var nowyear=2021;
var age=nowyear-year; //year为字符串型,这里用的减法,有隐式转换
alert('今年您'+age+'岁啦!');
2.简单加法器案例
var num1=prompt('请输入第一个值:');
var num2=prompt('请输入第二个值:');
var sum=Number(num1)+Number(num2);
var minus=num1-num2;
var mul=num1*num2;
var into=num1/num2;
alert('两个值之和为:'+sum);
alert('两个值相减为:'+minus);
alert('两个值相乘为:'+mul);
alert('两个值相除为:'+into);
3.依次询问并获取用户的姓名、年龄、性别,并打印用户信息(\n要放在引号里)
var myname=prompt('姓名'),age=prompt('年龄'),sex=prompt('性别');
alert('姓名:'+myname+'\n'+'年龄:'+age+'\n'+'性别:'+sex);

(3)转换成布尔型(boolean()函数)

代表空、否定的值( ' '、0、NaN、null、undefined)会被转换为false

!!'23'   转成布尔值

八、运算符

1.算数运算符(+ - * / %)

注:

(1)浮点数值得最高精度是17位小数,但在进行算数计算时其精确度远远不如整数。所以,不要直接判断两个浮点数是否相等var a=0.1+0.2;console.log(a==0.3);

(2)如果对两个字符串进行加法运算,则会做拼串(连接符)。即,任何的值和字符串做加法运算,都会先转换为字符串,然后再和字符串做拼串

1+2+”3”=33
“1”+2+3=123
100-“2”=98
2*“8“=16
2*null=0
// 小数与大数的余数为小数本身
2 % 7 = 2
(10-2) % 12 =8
2 % 7 - 9 / 3 = -1

JavaScript(2021.9.26)_第15张图片

任何值n取余,值为 0,1,2,... n-1
例:0,1,2,3,4,5,6   与3的余数
    0  1  2  0  1  2  0    0-2 

2.自增(++)和自减(--)运算符

  • 一元运算符包括 正负号、自增自减号;
  • 自增和自减运算符必须和变量配合使用,常用于计数

++a —> a=a+1            a++ —> a=a+1

(1)前置自增(++a) 先自加后返回值

(2)后置自增(a++) 先返回原值后加1

++a,--a  (在使用a之前,先使a的值加/减1)

a++,a--  (在使用a之后,使a的值加/减1)

var num1=10;  console.log(++num1 +10);   /*21*/
var num2=10;  console.log(num2++ +10);   /*20*/
// 后置自增(减)到了运算符的另一边完成自增(减)
var d=20;   var result=d++ + ++d + d ;   /*20+22+22=64*/
let a=3;    let result=++a + a++ + a++ + ++a   /* 4+4+5+7=20 */

3.比较运算符

JavaScript(2021.9.26)_第16张图片

1.==判等号(判断两边的值是否相等)
  console.log(18=='18');    /* true */
  console.log(1 == 'pink')  /* false 值根本不相等 */
2.===全等(两侧的值和数据类型完全一致才可以)
  console.log(18==='18')    /*false*/
  console.log(1 == 'pink')  /*false*/
3.!== 不全等(两边数据类型和值,只要有一个不等,就是true)
  console.log(18!==18)    /*false*/
  console.log(18!=='18')  /*true,类型不等*/
  console.log(25!==18)    /*true,值不等*/
4. > < <= >=   不同类型的比较会默认转换成number类型再比较(把字符串型的数据转换成数字型)

(1)比较运算符的返回值为true、false

(2)任何值和NaN做任何比较都是false

    10<="hello"  //false             true>false  //true        NaN===NaN  //false

(3)不要做小数运算,会有精度问题

0.1+0.2!=0.3
(0.1*10+0.2*10)/10=0.3      因为整数没有精度问题

(4)两个字符串比较:(比较字符对应的ASCII码)

JavaScript(2021.9.26)_第17张图片

4.逻辑运算符(&& || !)

(1)真假判断

与(&&) 两个都为真,返回值为真(true);其中一个为假,返回值就为假(false);

或(||) 其中一个为真,返回值就为真(true);两个都为假,返回值才为假(false);

非(!) 取反,真为假,假为真;

JavaScript(2021.9.26)_第18张图片

(2)短路运算(逻辑中断)

短路运算原理:当有多个表达式(非布尔进行与或运算)时,左边的表达式可以确定结果时(与&&遇假确定结果,或||遇真确定结果),就不再继续运算右边的表达式的值。

总结:与(&&)返回第一个为false的值;或(||)返回第一个为真的值。

1)逻辑与

   语法:表达式1 && 表达式2

   如果第一个表达式的值为true,则返回表达式2;如果两个值都为true,则返回后边的;

   如果第一个表达式的值为false,则返回表达式1;如果两个值都为false,则返回前边的;

注意:返回的值不是true/false,因为与、或、非没有能力将两侧的值转为true、false,只是判断值为真还是假

console.log(123 && 456);         /*456*/
console.log(123 && 456 && 1+2);  /*3*/

//左边如果是 0 '' undefin null NaN 则返回自身
console.log(0 && 456);           /*0*/
console.log(null && 456);        /*null*/
console.log(0 && 456 && 1+2);    /*0*/

2)逻辑或

语法:表达式1 || 表达式2

如果第一个表达式的值为真,则返回表达式1;

如果第一个表达式的值为假,则返回表达式2.

console.log(123 || 456);         /*123*/
console.log(0 || 456 || 1+2);    /*456*/
例:
var num=0;
console.log(123 || num++);  /*中断运算*/
console.log(num);           /*0*/

5.赋值运算符

例:num += 3 —> num=num+3

JavaScript(2021.9.26)_第19张图片

6.运算符优先级

JavaScript(2021.9.26)_第20张图片

九、流程控制(顺序结构、分支结构、循环结构)

1.顺序流程控制

顺序结构是程序中最简单、最基本的流程控制,程序会按照代码的先后顺序,依次执行。

2.分支流程控制

  • 根据不同的条件,执行不同的路径代码(多选一),从而得到不同的结果。
  • 如果条件不是布尔类型,会隐式转换为布尔类型,如,if (a) {alert('监督局')}

(1)if 语句

1.if-else 双分支
  if (条件) 
     {语句1;} 
  else
     {语句2;}

2.if-else if 多分支(检查多重条件,可以处理范围)
  if (条件1) 
     {语句1;} 
  else if (条件2)
     {语句2;}
  else if (条件3)
     {语句3;}
  else
     {语句4;}
判断是否能进入网吧
var age=+prompt("请输入您的年龄:");
if (age>=18) {
	alert('允许进入网吧!');
} else{
	alert('抱歉,您还未成年!');
}

判断闰平年(能被4整除且不能整除100的年份为闰年或者能够被400整除的就是闰年)
var year=+prompt("请输入年份:");
if (year%4==0&&year%100!=0||year%400==0) {
	alert(`${year}为闰年`);
} else{
	alert(`${year}为平年`);
}

(2)三元表达式

条件表达式 ?表达式1 :表达式2;

如果条件表达式为真,则返回表达式1;如果条件表达式为假,则返回表达式2。(简化版的if-else,一般用于赋值,比如最大值比较,将最大值赋给变量)

补0操作,可用于倒计时(小于10的数补零,大于10的数不补零)
方法一:
var num=prompt("请输入一个数字:");
num<10 ? alert('0'+num+' 补零') : alert(num+' 不补零');
方法二
var num=prompt("请输入一个数字:");
var result= num<10 ? '0'+num+' 补零' : num+' 不补零';
alert (result);

(3)switch-case

一般用于等值判断,不适合于区间判断

switch (表达式/变量){
	case 值1:语句1;
		break;       //break 跳出
	case 值2:语句2;
		break;
	...
	default:
		break;
}

注:

1)case后面必须是一个整数,或是结果为整数的表达式,但不能包含任何变量

2)若某一条case后没有紧跟的语句,则不用带分号和break

3)表达式/变量的值和case里的值匹配时,得是全等关系(值和数据类型都得相同)

4)如果当前的case里没有break,则不会退出,会继续执行下一个case

5)若没有default,并且和任何case值不匹配时,则跳出switch,什么都不执行

1. 查询水果价格
var fruit=prompt("请输入一种水果:");
switch (fruit){
	case '苹果':alert("苹果 0.8/斤");    //水果名称要加引号,因为要全等匹配
		break;
	case '香蕉':alert("香蕉 1.5/斤");
		break;
	case '草莓':alert("草莓 2/斤");
		break;
	default:alert("无此种水果");
		break;
}

2. 用户输入2个数字

3.循环流程控制

在程序中,一组被重复执行的语句被称之为循环体,能否继续重复执行,取决于循环的终止条件。由循环体及循环的终止条件组成的语句,被称之为循环语句

循环的目的:重复的执行某些代码。

(1)for循环及双重for循环

for (初始化变量 ; 条件表达式 ; 操作表达式) {循环体}

for (var i=1,j=0 ; i<=10 ; i=i+2) {循环体}
(1)注意是var,不是int
(2)当有多个初始化变量时,要用“,”隔开
(3)for循环的变量(int i)是个局部变量,只在for循环体里有效
for循环可以嵌套if语句
  for (var i=1;i<=20;i++) {
	  if (i==1){
		  console.log('1岁了,出生年!');
	  }
	  else if (i==18) {
	  	console.log('18岁,成年了!');
	  }
	  else {console.log('今年'+i+'岁了');}
  }

1-100的总和、平均值、奇数、偶数、能被3整除的数字的和
  var sum=0,odd=0,even=0,result=0;
  for (var i=1;i<=100;i++) {
	  sum+=i;     //总和

	  if (i%2!=0) {  //奇数
		  odd+=i;
	  }
	  else {even+=i;}  //偶数

	  if (i%3==0){    //能被3整除的
	 	  result+=i;
	  }
  }
  document.write('和为:'+sum,'平均数为:'+sum/100,'奇数'+odd,'偶数'+even,'能被3整除的数字的和'+result);

输入班级人数并计算出总成绩和平均成绩
  var num=prompt ('请输入班级人数:');
  var sum=0;
  for (var i=1;i<=num;i++) {
	  var sorce=prompt ('请输入第'+i+'个人的成绩:')
	  sum+=parseFloat(sorce);   //prompt取过来的是字符型,需要转换成数字型
  }
  alert('班级总成绩为:'+sum);
  alert('班级平均成绩为:'+sum/num)

for循环双层嵌套
for(外边循环变量的起始值;循环条件;变化值){
    for(里边循环变量的起始值;循环条件;变化值){
    }
}


JavaScript(2021.9.26)_第21张图片

JavaScript(2021.9.26)_第22张图片

图一:一行打印5颗♥   重点:转换为字符串就可以在一行上打印出
  var str='';
  for(i=1;i<=5;i++){
    str=str+'♥';
  }
  console.log(str);

图二:五行五列
  var str='';
  for(i=1;i<=5;i++){       //外面for是列,控制里层for要循环多少次
	  for(j=1;j<=5;j++){   //里面for是行,控制每一行的个数
	    str=str+'♥';
	  }
	  str=str+'\n';
  }
  document.write(str);

图三:倒三角
  var str='';
  for(i=1;i<=10;i++){
    for(j=i;j<=10;j++){    //(j=10;j>=1;j--)错误,因为这样每次循环j=10,所以最后结果的每行都是10个
      str=str+'♥';
    }
  str=str+'\n';
  }
  console.log(str);

正三角
  var str='';
  for(i=1;i<=10;i++){
    for(j=1;j<=i;j++){
      str+='♥';
    }
  str+='\n';
  }
  console.log(str);

九九乘法表
  var str='';
  for(i=1;i<=9;i++){
    for(j=1;j<=i;j++){   //每一行公式的个数正好和行数一致,所以 j<=i
      str+=j+'*'+i+'='+j*i+'\t';   //j*i=行*列
    }
    str+='\n';
  }
  console.log(str);
打印在网页中(\n只是输出一个空格;
在JS里也是换行) for(i=1;i<=9;i++){ for(j=1;j<=i;j++){ document.write(j+'*'+i+'='+j*i+'\t'); } document.write('
'); }

(2)while循环及do-while循环

1.while (先判断 再执行)
  var 声明变量并初始化;
  while(循环条件) 
    {循环体;}

2.do-while (先执行 再判断)
  do {循环体;}
  while (循环条件);
循环案例
1.打印人的一生,从1岁到100岁
(1)while
  var age=1;
  while(age<=100) 
    {document.write('今年'+age+'岁了!'+'
'); age++;} (2)do-while var age=1; do{ document.write('今年'+age+'岁了!'+'
'); age++; }while(age<=100); 2.计算1-100之间所有整数和 (1)while var num=1,sum=0; while(num<=100){ sum+=num; num++; } document.write(sum); (2)do-while var num=1,sum=0; do{ sum+=num; num++; }while(num<=100); document.write(sum); 3.弹出一个提示框'love?',如果输入'yes'就结束,否则就一直询问 (1)while var answer=prompt('love?'); while(answer!='yes'){ answer=prompt('love?'); //不能只写prompt('love?'); 要给它一个变量保留它的值,才能返回判断,否则会陷入死循环 } (2)do-while var answer=prompt('love?'); do{ answer=prompt('love?'); }while(answer!='yes'); (3)开关法(不确定循环的次数)

(3)for循环与while循环在什么情况下使用

循环次数已知的,用for循环;循环次数未知的用while循环;

用来计数,跟数字有关,常用for;

while和do-while可以做更复杂的判断条件,比for循环更灵活。

(4)跳转循环语句(continue / break / goto)

break 跳出当前整个循环,只能跳出一层循环
continue 结束本次循环,判断循环条件,如果成立,则进入下一次循环,否则退出整个循环
goto 跳出多层循环
1. 求1-100之间,除了能被7整除之外的整数和
	var sum=0;
	for(var i=1;i<=100;i++){
		if(i%7==0){
			continue;
		}
		sum+=i; 
	}
	document.write(sum);

2. 打印1-10的奇数
// 思路:跳过偶数,打印奇数
        for(let i=1;i<=10;i++){
            if(i%2===0){
                continue
            }
            console.log(i)
        }

3. 求1-100前3个能被7整除的数的和
        let sum = 0
        let count = 0   //计数器
        for (let num = 1; num <= 100; num++) {
            if (num % 7 === 0) {
                count++
                
                // 当次数为4时就跳出循环
                if (count === 4) {
                    break
                }
                sum += num

                // 当计数器写在和的下面时,到3次时就要跳出循环
                /* if (count === 3) {
                    break
                } */
            }
        }
        console.log(sum)

4.综合案例—简易ATM

JavaScript(2021.9.26)_第23张图片

方法一:
// 开关法循环,在循环外边定义一个变量为true,进入循环体里边去,想要结束循环,变量在循环里=false
        let flag = true,
            money = 0
        while (flag) {
            let num = +prompt(`请选择您的操作:
            1. 存款
            2. 取款
            3. 查看余额
            4. 退出`)
            switch (num) {
                case 1:
                    let add = +prompt('请输入存款金额:')
                    money += add
                    break
                case 2:
                    let get = +prompt('请输入存款金额:')
                    money -= get
                    break
                case 3:
                    alert(`余额为${money}`)
                    break
                case 4:
                    flag = false
                    break
                default: alert('请输入正确序号')
            }
        }


方法二:
alert('欢迎登入!');
var money=0;
for (var i=1;i>=1;i++){
	var num=prompt('请输入您要的操作:'+'\n'+'1.存钱'+'\n'+'2.取钱'+'\n'+'3.查询余额'+'\n'+'4.退出')
  //一开始的输入框要写在for循环内,才能每次返回到开始的界面
	if (num=='1') {
		money1=prompt('请输入存的钱数:');
        money+=parseFloat(money1);
		alert('现在余额为:'+parseFloat(money));
	}
	else if (num=='2') {
		cut=prompt('请输入取的钱数:');
		cut=parseFloat(cut);
		if (cut<=money){
			money=parseFloat(money-cut);
		    alert('现在余额为:'+money);
		}
		else {alert('余额不足!');}
	}
	else if (num=='3') {
		alert('现在余额为:'+parseFloat(money));
	}
	else if (num=='4') {
		alert('现在正在退出!');
		break;
	}
	else {alert('请按要求输入!');}
}

5.计数器

// 计算数组[2,6,18,15,40] 中能被3整除的偶数的个数
        let arr = [2, 6, 18, 15, 40]
        let count = 0
        for (let i = 0; i < arr.length; i++) {
            if (arr[i] % 3 === 0 && arr[i] % 2 === 0) {
                count++
            }
        }
        console.log(count)

十、数组

1.数组的概念

数组是指一组数据的集合,其中的每个数据被称作数组元素,在数组中可以存放任意类型的元素。数组是一种将一组数据存储在单个变量名下的方式。

2.创建数组

数组中可以放任意类型的数据;数组元素之间要用','逗号隔开。

1)利用数组字面量创建数组

var 数组名=[ ];
var a=[20,'城南',true];

2)利用new创建数组

var 数组名=new Array( );   注意A要大写
var a = new Array(1,'短信',true);

3.获取数组元素

数组名[元素的索引号]
a[2]  获取a数组中索引号为2的元素。如果没有这个数组元素,输出的结果会是 undefined

索引(下标):用来访问数组元素的序号(数组索引号从0开始

4.遍历数组(利用for循环)

遍历:把数组中的每个元素从头到尾都访问一次。

?结果有问题      不能用name作为数组名,因为name是关键词

?结果无引号      alert无引号,console.log控制~台有引号

var forename=['刘备','关羽','张飞','马超'];
for(var i=0;i<4;i++){    //i从0开始;i<=元素个数(forename.length)
	console.log(forename[i]);
}

5.数组的长度

数组名.length
a.length   //数组a中元素的个数,length为变量属性名

 6.数组的增删改查

(1)修改数组索引,添加/更改数组元素

数组名[索引号]

用来判断数组中是否包含某个对象或值

indexOf或findIndex()

数组名[索引号]=要改成的值
数组名.push(数据1,数据2,...数据n) 新增加的数组元素在数组的末尾
console.log(数组名.push(数据1,数据2,...数据n)) 打印此语句,返回新数组的长度
数组名.unshift(数据1,数据2,...数据n) 新增加的数组元素在数组的前边
console.log(数组名.unshift(数据1,数据2,...数据n)) 打印此语句,返回新数组的长度
数组名.pop( ) 删除数组的最后一个元素
数组名.shift( ) 删除数组的第一个元素
console.log(数组名.pop( )) 返回被删除的元素
console.log(数组名.shift( ))
数组名.splice(开始删除元素的索引值,删除的数量,新增数据1,新增数据2)

批量删除(抽奖、购物车)

返回被删除的元素

数组名.filter( )            // 过滤
var str=['红','绿','蓝','白'];
str[0]='黄';         //更改  结果:黄,绿,蓝,白

str[5]='黑';         //添加  结果:红,绿,蓝,白,黑
str.push=[1,2]       //添加  结果:红,绿,蓝,白,1,2
console.log(str.push=[1,2])  // 结果:6(长度)
str.unshift=[A,B,C]  //添加  结果:A,B,C,红,绿,蓝,白
console.log(str.unshift=[A,B,C])   // 结果:7(长度)

str.pop()                // 删除  结果:'红','绿','蓝'
console.log(str.pop())   // 结果:'白'
str.shift()              // 删除  结果:'绿','蓝','白'
console.log(str.shift()) // 结果:'红'
str.splice(1,2)          // 批量删除  结果:'红','白'
str.splice(1)            // 批量删除  结果:'红'  (将起使元素后面的元素都删除)
str.splice(1,1)          // 批量删除  结果:'红','蓝','白'  (只删除起使元素)

str='赋值没加索引';  //结果:赋值没加索引
  注意:不能直接给数组名赋值,否则会覆盖掉以前的数据

(2)修改length,实现数组扩容

数组名.length=想要扩到的长度;
a.length=7;

7.数组的方法

数组的方法 作用 举例

reverse

翻转数组顺序

数组名.reverse()

indexOf

在数组中查找某项首次出现的索引位置,找到返回索引值,找不到返回 -1

可用来判断数组中是否包含某个对象或值

数组名.indexOf('数组中的某一项元素')
lastIndexOf 在数组中查找某项最后出现的索引位置,找到返回索引值,找不到返回 -1 数组名.lastIndexOf('数组中的某一项元素')

join

拼接数组的每个元素成为字符串

数组名.join('拼接的符号或为空')

concat 拼接数组成为新数组

a.concat(b, c, 'aa', 'bb', 'cc')

把数组b/c及'aa'等拼接到数组a后面

数组的静态方法 作用 举例
Array.isArray(数组名) 判断是否是数组类型,返回布尔值

let arr=[1,2,3]

Array.isArray(arr)

Array.from(伪数组名)

把伪数组转换为真数组

注意:转真数组时,伪数组必须有length属性,length可以比伪数组元素的数量多(undefined)或少(有几个就显示几个)

let as = {

            0: 'a',

            1: 'b',

            2: 'c',

            3: 'd',

            4: 'e',

            length: 6

        }

Array.from(as)

遍历数组的方法:7种
    每个方法都有3个形参:
    item     第一个参数,代表当前项(arr[i])
    index    第二个参数,代表当前项的索引值(i)
    o        第三个参数,代表当前数组(arr)

        let arr = [3, 2, 6, 7, 9, 4]   // 全局数组变量

1. forEach:遍历数组
		arr.forEach(function (item, index, o) { console.log(item) })
		arr.forEach(item => console.log(item))   // 箭头函数

2. filter:过滤  筛选出满足条件的值放到数组中返回,可用于删除
		let re = arr.filter(function (item) {
			return item % 2 === 0    // 返回偶数
		})
		console.log(re)    // 结果:[2,6,4]

3. map:依次让每个元素执行一遍回调,把结果全部放到数组中返回
		let re = arr.map(function (item) {
			return item * item
		})
		console.log(re)    // 结果:[9,4,36,49,81,16]

 4. find:遍历查找满足条件的首个元素,并返回这个元素
		let re = arr.find(function (item) {
			return item >5
		})
		console.log(re)    // 结果:6

 5. findIndex:遍历查找满足条件的首个元素,并返回这个元素的索引值
    可用来判断数组中是否包含某个对象或值
		let re = arr.findIndex(function (item) {
			return item > 5  或  item.name=='张三'
                   大于5的值     数组中name为张三的对象
		})
		console.log(re)    // 结果:2

6.  some:遍历查找是否有满足条件的值,有一个就立刻返回true,没有则返回false
		let re = arr.some(function (item, index) {
			console.log(index)    // 输出:0 1 2  说明有一个满足条件就立刻返回
			return item > 5
		})
		console.log(re)    // 结果:true

7. every:遍历查找满足条件的值,都满足返回true,有一个不满足就返回false
		let re = arr.every(function (item, index) {
			console.log(index)    // 输出:0 1   说明有一个不满足条件就立刻返回false
			return item > 2
		})
		console.log(re)    // 结果:false

7.筛选数组

将数组[2,0,6,1,77,0,52,0,25,7]中大于等于10的元素选出来,放入新数组
  方法一:
    var num=[2,0,6,1,77,0,52,0,25,7];
    var num1=[];
    var j=0;
    for(var i=0;i=10){
    		num1[j]=num[i];
    		j++;
    	}
    }
    alert(num1);
  方法二:(不用申请新变量j)
    var num=[2,0,6,1,77,0,52,0,25,7];
    var num1=[];  //空数组length为0
    for(var i=0;i<10;i++){
    	if(num[i]>=10){
    		num1[num1.length]=num[i];  //length自动检测数组的长度
    	}
    }
    alert(num1);
方法三:
        let arr=[2,0,6,1,77,0,52,0,25,7]
        // 思路:遍历数组,筛选出>=10的元素,用if追加到新数组
        let newArr=[]
        for(let i=0;i<=arr.length;i++){
            if(arr[i]>=10){
                newArr.push(arr[i])
            }
        }
        console.log(newArr)

8.删除指定数组元素(去重)

1. 将[2,0,6,1,77,0,52,0,25,7]中的0去掉后,形成一个不包含0的新数组
	var num=[2,0,6,1,77,0,52,0,25,7];
	var num1=[];
	for(i=0;i
2. 需求:将不重复的元素放入新数组
   思路:依次获取数组arr的值,去newArr里查看是否有这个元素,如果没有这个值就添加

		let arr = ['a', 1, 2, 'b', 'a', 'c', 'd', 1, 'a', 3, 2]
		let newArr = []
		for (let i = 0; i < arr.length; i++) {
			if (newArr.indexOf(arr[i]) === -1) {
				newArr.push(arr[i])
			}
		}
		console.log(newArr)

9.翻转数组

将数组[1,2,3,4,5]的内容反过来存放,输出:[5,4,3,2,1]
  方法一:
	var num=[1,2,3,4,5];
	var num1=[];
	for(var i=num.length-1;i>=0;i--){           *不同处
		num1[num1.length]=num[i];               *
	}
	alert(num1);
  方法二:
	var num=[1,2,3,4,5];
	var num1=[];
	for(var i=0;i

10.数组排序(冒泡排序)

冒泡排序:把一系列的数据按照一定的顺序进行排列显示(从小到大或从大到小)。

冒泡排序一次比较两个元素,如果它们的顺序错误就把它们交换过来,否则不交换。

JavaScript(2021.9.26)_第24张图片

	var num=[1,2,3,4,5];                      //可以是任意数组
	for(var i=0;i<=num.length-1;i++){         //外层循环总共的趟数(元素个数-1)
		for(var j=0;j<=num.length-1-i;j++){   //内层循环每趟比较的次数(元素个数-1-趟数)
			if(num[j]

案例

1.返回数组的和、平均值及最大值
    var num=[2,6,1,7,4];
    var sum=0;
    var max=num[0];
    for(i=0;i

十一、函数

函数与循环的区别:循环是一次把所有次数执行完,不方便控制执行的位置;函数时需要的时候就调用一次。

函数就是封装了一段可以被重复执行调用的代码块(封装了一定功能),可进行复用。

封装:把一个或多个功能通过函数的方式封装起来,对外只提供一个简单的函数接口。

1.函数的声明与调用

 书写格式  例子
声明函数 function

function 函数名() {

        函数体代码;

}

函数名();

function getsum(num1

 ) {

        for(i=0;i         sum+=num1[i];
        }

}

getsum(20);

//求1~20的和

调用函数 函数名();
注:声明函数本身并不会执行函数,只有调用函数时才会执行函数体代码(即,两者相互配合使用)

函数名的命名和变量相同,一般以动词为前缀

JavaScript(2021.9.26)_第25张图片

2.函数的参数

所在位置 说明 关系
形参

function 函数名(形参1,形参2) {

        函数体代码;

函数名(实参1,实参2);

在声明函数的小括号里面是形参

函数定义的时候传递的参数(形式上的参数)

1.实参把值传递给形参;形参是接受实参的

2.函数的参数可以有多个(多个参数用逗号隔开),也可以没有

3.开发中尽量保持形参和实参个数一致 

4.实参可以是任意的数据类型,数组/变量

实参

在调用函数的小括号里面是实参

函数调用的时候传递的参数(实际的参数)

逻辑中断的巧用

  • 形参如果不被赋值,就是undefined
  • 利用逻辑中断,将输入的非法值转化合法的
//形参如果不被赋值,就是undefined
        function getSum(num1, num2) {
            // 利用逻辑中断,将输入的非法值转化成0,使之能顺利进行计算
            //或运算找true
            num1 = num1 || 0
            num2 = num2 || 0
            console.log(num1 + num2)
        }
        //多余的实参(3,5)不会传入函数
        getSum(2, NaN, 3, 5)    //结果:2

3.函数返回值(return)

作用:把处理结果返回给调用的函数,可在函数外使用

关键词:return

语法:return   数据
           return [num1, num2]       (返回多个值时,保存到数组里,再返回给函数调用)

function getSum(num1, num2) {
      // 将值返回给调用的函数
      return num1 + num2
      //此语句不会执行,因为return会立即结束当前函数
      document.write('123')
}
console.log(getSum(2, 5)+10)
或
let sum=getSum(2, 5)
console.log(sum);

注意:

  • 在函数体中使用 return 关键字能将内部的执行结果交给函数外部使用
  • 函数没有 return 时,函数默认返回值为 undefined
  • 函数内部只能出现 1 次 return,并且 return 后面代码不会再被执行,所以 return 后面的数据不要换行写
  • return会立即结束当前函数

4.作用域

  • 作用域定义:代码(变量)的可用性范围
  • 作用:作用域提高了程序逻辑的局部性,增强了程序的可靠性,减少了名字冲突

(1)作用域

作用域分类 说明 注意
全局作用域 函数外部或者整个script 有效 如果函数内部或者块级作用域内部,不声明直接赋值使用的变量,是全局变量
局部作用域 函数内部有效,也称为函数作用域

函数的形参可以当做局部变量;

为什么在函数内部声明的变量只能在函数内部被访问,外部无法直接访问 :

执行函数时会开拓出一块区域存放局部变量,执行完就销毁了,所以外部无法直接访问

块级作用域 { } 内有效,包括,if语 句和for语句里面的{ }等
变量分类 说明
全局变量 函数外部let 的变量 全局变量在任何区域都可以访问和修改
局部变量 函数内部let的变量 局部变量只能在当前函数内部访问和修改
块级变量 {} 内部的let变量 let定义的变量,只能在块作用域里访问,不能跨块访问,也不能跨函数访问
let a = 1         // 全局变量
function fn() {
    let b = 2     // 局部变量
    if (true) {
       let c = 3  // 块级变量
    }
}
fn()

(2)作用域链

作用域链,由作用域串联起来的链状结构(就近查找,如果没有,去上一级)

怎么看一个区域是否有变量:是否有var / let / cost 关键词,否则是使用变量。

作用:提供查找变量的机制。

(3)闭包

定义:闭包是一个作用域有权访问另外一个(上级)作用域的变量;

判断是否产生闭包:断点调试出现closure;

作用:可以把一个变量使用范围延伸(局部变量在外边也能用)

  1. 闭包本质仍是函数,只不是从函数内部返回的;

  2. 闭包能够创建外部可访问的隔离作用域,避免全局变量污染;

  3. 过度使用闭包可能造成内存泄漏;

注:回调函数也能访问函数内部的局部变量。

let num = 123;
function f1 () {
	let n = 666;
	return function () {console.log(n);}  // 这个函数是闭包函数
}
let re = f1();  // 返回的是一个函数  结果:function () {console.log(n);}
re();  // 调用返回的这个函数 结果:666
闭包的作用:避免变量污染
let uname='阿飞'
function fn(){
    let uname='小狸'
    return function(){
        console.log(uname)
    }
}
fn()()    // 实现闭包,局部变量在外面也能用

(4)预解析 (变量提升)

名次 说明
预解析 代码在执行之前先要解析一边,预解析分为 变量提升 和 函数提升。
变量提升 带有声明的变量,把声明变量的语法提升到当前作用域最前边(注意:只声明不赋值
函数提升 带有声明的函数,把声明函数的语法提升到当前作用域最前边(注意:只声明不调用

注意点:

  • 变量在未声明即被访问时会报语法错误;变量在声明之前即被访问,变量的值为 undefined
  • 函数优先:
  • console.log(a)   // 函数a
    function a() {
    	console.log('aa')  
    }
    var a = 1
    console.log(a)   // 1
  • let 声明的变量不存在变量提升(报的错应该是:变量未定义),推荐使用 let【也有人认为具有提升但是不赋值不能使用(因为报的错是:初始化之前不能使用)】
var a=b=c=9
等于
var a=9
b=9    b / c 没有关键词,为全局变量
c=9

5.匿名函数

(1)函数表达式

将匿名函数赋值给一个变量,并且通过变量名称进行调用 我们将这个称为函数表达式

let 变量名 = function () {
    匿名函数内的代码
}
变量名()    // 调用函数

例:
let fn = function () {
    console.log(111)
}
fn()
函数也是一种数据

(2)立即执行函数

  • 定义:只执行1次的自调用函数
  • 作用:避免全局变量之间的污染
  • 注意: 多个立即执行函数前要用 ; 隔开,要不然会报错,避免和前面的语句连起来
写法一:
    ;(function () {
         console.log(111)
         })()

写法二:
    ;(function () {
         console.log(111)
     }())

 6. 箭头函数(=>)

语法:

  • 箭头函数是一种声明函数的简洁语法,不存在预解析 ;
  • 箭头函数只有一个参数时可以省略圆括号 ()
  • 箭头函数函数体只有一行代码时可以省略花括号 {},并自动做为返回值被返回
  • 举例: 
    // 具名函数
        function fn() { }
    
    // 箭头函数:相当于具名函数
        let fn = () => { 代码块 }
        fn()
    
    // 1. 1个形参省略()
    // 2. 1句代码块省略{ }
        let fn = n => n * n
    	fn(3)  // 9
    
    // 3. 定时器中的箭头函数
        setInterval(() => { }, 1000)
        setInterval(function () { }, 1000)

注意:

  • 箭头函数属于表达式函数,因此不存在预解析,所以必须先定义再使用
  • 箭头函数中没有 arguments,只能使用 ... 动态获取实参
  • 涉及到this(指向调用者) 的使用,不建议用箭头函数(所用this指向上级作用域的this)
  • let obj = {
    	uname: 'SHY',
    	age: 18,
    	school: function () {
    			console.log(this)     // this指的是obj
    			window.setInterval(() => {console.log(this)}, 1000)}   // this指的是obj,不是window
    }

7. 参数

(1)默认值

  • 声明函数时为形参赋值即为参数的默认值;
  • 如果参数未自定义默认值时,参数的默认值为 undefined;
  • 调用函数时没有传入对应实参时,参数的默认值被当做实参传入;
 // 设置参数默认值
function sayHi(name="小明", age=18) { }
sayHi( undefined, 20);   // undefined是用来给name占位的
        name      age

(2)动态参数(arguments)

函数的返回值arguments的使用函数的两种声明方式

  • arguments是函数里边的内置的伪数组变量(对象);
  • arguments是伪数组,没有push/pop 这些方法,存的是实参,可以批量处理实参;
  • 作用:用于接收传入的所有实参;
  • 使用情况:参数个数不固定时使用argument接受实参;
//取实参中的最大值
    //方法一:用arguments函数返回值
        function getMax() {
            let max = arguments[0]
            for (let i = 0; i < arguments.length; i++) {
                if (max < arguments[i]) {
                    max = arguments[i]
                }
            }
            return max
        }
        let num = getMax(5, 30, 12, 50, 25)
        console.log(`实参中的最大值是${num}`)

    //方法二:老方法,将实参装入数组中
        function getMax(a,b,c,d,e) {
            let arr = [a,b,c,d,e]
            let max=arr[0]
            for (let i = 1; i < arr.length; i++) {
                if (max < arr[i]) {
                    max = arr[i]
                }
            }
            return max
        }
        let num = getMax(5, 30, 12, 50, 25)
        console.log(`实参中的最大值是${num}`)

(3)剩余函数(...)

  • ... 是语法符号,置于最末函数形参之前,用于获取多余的实参;
  • 借助 ... 获取的剩余实参;
  • 可替换 arguments;
// ...将实参以数组形式存入num中
		function log(...num) {
			let sum = 0
			for (let i = 0; i < num.length; i++) {
				sum += num[i]
			}
			console.log(sum);
		}
		log(1, 2, 3, 4, 5, 6, 7, 8, 9)

8.高阶函数、回调函数

当一个函数A给另外一个函数B当做参数的时候,A函数就是回调函数,B函数就是高阶函数

函数也是一种数据类型。

1. fun函数是高阶函数,给fun当参数的匿名函数是回调函数
    function fun ( n ) {n();}
    fun( function () {console.log('aa');} );

2. 事件:
    document.addEventLisntener('click', function () { });
                                         回调函数
3. 定时器
    setInterval( function () { }, 1000 );
      高阶函数     回调函数

9.利用递归求n的阶乘


利用递归函数求1~n的阶乘 1 * 2 * 3 * 4 * ..n
        let num = +prompt('请输入一个数字,计算1到这个数的阶乘:')
        function getN() {
            if (num === 1) {
                return 1
            }
            else if (num > 0) {
                return num * getN(num - 1)
            }
        }
        alert(`阶乘为${getN()}`)
        getN()

10.环境对象(this) 

环境对象指的是函数内部特殊的变量 this

this指向调用者

函数案例

1.利用函数计算1-100之间的累加值

function getsum(num) {
	var sum=0;
	for (i=0;i<=num;i++) {
		sum+=i;
	}
	alert("累加和为:"+sum);
}
getsum(100);

2.用函数求任意两个数之间的和

function getsum(start,end) {
	var sum=0;
	for (i=start;i<=end;i++) {
		sum+=i;
	}
	alert(start+"与"+end"之间的累加和为:"+sum);
}
/*getsum(start,end); */
getsum(2,10);      /*求的是2~10之间的累计和*/

3.求2个数的和 

// 方法一:将实参传入函数
        function getSum(num1, num2) {
            alert(num1 + num2)
        }
        getSum(2, 3)
        getSum(24, 56)

// 方法二:之前的写法,然后封装
        function getSum1() {
            let num1 = +prompt('输入第一个数')
            let num2 = +prompt('输入第二个数')
            alert(num1+num2)
        }
        getSum1()

4.求学生总分

// 求学生总分
        function getSum(arr) {
            let sum = 0
            for (let i = 0; i < arr.length; i++) {
                sum += arr[i]
            }
            console.log(sum)
        }
        // 实参可以是任意的数据类型
        getSum([10, 20, 30])
        let shy = [20, 30, 40, 100, 50]
        getSum(shy)

4-1.求一个数组最大值和最小值

// 求一个数组最大值和最小值
        function getNum(arr) {
            // 假设第一项为最大值/最小值
            let max =  min = arr[0]
            // 因max = arr[0],所以 i = 1 可减少一次循环
            for (let i = 1; i < arr.length; i++) {
                if (max < arr[i]) {
                    max = arr[i]
                }
                if (min > arr[i]) {
                    min = arr[i]
                }
            }
            // 返回多个值时,保存到数组里,再返回给函数调用
            return [max, min]
        }
        let res= getNum([20, 50, 30, 10, 40, 100])
        console.log(`该数组的最大值为${res[0]},最小值为${res[1]}`)

4-2.求一个数组最大值和最小值的变种

// 求一个数组最大值和最小值
// 函数调用的时候,如果第二个参数为true,返回最大值;如果没有第二个参数,返回最小值
        function getNum(arr,flag) {
            let max =  min = arr[0]
            for (let i = 1; i < arr.length; i++) {
                if (max < arr[i]) {
                    max = arr[i]
                }
                if (min > arr[i]) {
                    min = arr[i]
                }
            }

            if(flag){
                return max
            }
            else{return min}
        }
        let res= getNum([20, 50, 30, 10, 40, 100],true)
        let res1= getNum([20, 50, 30, 10, 40, 100])
        console.log(res)
        console.log(res1)

5.求两个数的最大值

// 求两个数的最大值
// 用户输入两个值,比较大小,封装函数,将大的值返回到函数外边,在页面中打印出来
        function getNum(num1, num2) {
            num1 = +prompt('请输入第一个数值:')
            num2 = +prompt('请输入第二个数值:')

            return num1 > num2 ? num1 : num2
            三元表达式 或 if表达式
            if (num1 > num2) {
                return `最大值为${num1}`
            }
            else if (num1 < num2) {
                return `最大值为${num2}`
            }
            else {
                return `两值相等`
            }
        }
        alert(getNum())

6.时间转换 (用户输入秒数,可以自动转换为天时分秒)

// 用户输入秒数,可以自动转换为天时分秒
        let num = +prompt('请输入要转换的秒数:')

        function getTime(time) {
            // 天时分秒的转换,只取整数
            // 任何值n取余,值为 0,1,2,... n-1
            let day = parseInt(num / 60 / 60 / 24)
            let hour = parseInt(num / 60 / 60 % 24)   // 1天 0-23小时
            let min = parseInt(num / 60 % 60)         // 1小时 0-59分钟
            let sec = parseInt(num % 60)              // 1分钟 0-59秒

            // 三元表达式补0操作
            day = day <= 9 ? '0' + day : day
            hour = hour <= 9 ? '0' + hour : hour
            min = min <= 9 ? '0' + min : min
            sec = sec <= 9 ? '0' + sec : sec

            // 函数返回值,一次返回多个数据,用数组
            return [day, hour, min, sec]
        }
        let time = getTime(num)      // 调用函数,实参也可以是变量
        document.write(`${num}秒被转换成${time[0]}天${time[1]}时${time[2]}分${time[3]}秒`)

十二、对象

1.定义

  • 对象(object):JavaScript里的一种数据类型;
  • 对象是无序的数据的集合;
  • 可以详细的描述描述某个事物(对象保存多个关联性比较大的属性);

2.对象的使用

(1)声明对象

let 对象名 = {        //对象声明
    属性名: 属性值,
    方法名: 匿名函数
}

let Person = {
    uname:'大黄',
    sayHi:function() { console.log('sayHi方法') },   // 方法的函数内可以传参数
    'play ball': function () { }                    //方法名也可加引号,方法之间也用逗号隔开
}

(2)访问对象的属性/方法

属性访问的2种方法    获取对象里的属性值
    (1)对象名.属性名    访问固定属性
        console.log(person.my - name)  // 不生效
        console.log(person.age)
    (2)对象名['属性名']    访问动态属性
        console.log(person['my-name'])
        console.log(person['sex'])


方法访问的2种方法    调用对象里的方法
    (1)对象名.方法名()
        person.sing(123)           // 可以传参
        person.'play ball'()       // 错误,多个单词的方法名必须用[]
    (2)对象名['方法名']()
        person['sing']()
        person['play ball']()

注意:
    [] 里面的属性名一定加引号;
    当属性为动态时用 []

3.操作对象(增删改查)

增删改都是基于查的语法之上的。

1. 改(重新赋值)    在对象外操作
    (1)对象名.属性名=属性值
        person.age = 99
        console.log(person.age)
    (2)对象名['属性名']=属性值
        person['my-name'] = '明明'
        console.log(person['my-name'])

    (3)对象名.方法名 = 匿名函数     定义时带引号的方法名用此不生效
        person.sing = function () {
            console.log('sing改1')
        }
        person.sing()
    (4)对象名['方法名']=匿名函数
        person['sing'] = function () {
            console.log('sing改2')
        }
        person.sing()

        person['play ball'] = function () {
            console.log('play ball改2')
        }
        person['play ball']()


2. 增
    (1)对象名.新属性名 = 新属性值
         对象名.新方法名 = 新匿名函数
        person.school = 'sjzxy'
        person.drink = function () {
            console.log('喝mink')
        }
    (2)对象名['新属性名'] = 新属性值
         对象名['新方法名'] = 新匿名函数


3. 删
    (1)delete 对象名.属性名
         delete 对象名.方法名
            delete person.age
            delete person.sing

    (2)delete 对象名[属性名]
         delete 对象名[方法名]
            delete person['sex']
            delete person['my-name']
            delete person['play ball']

4.遍历对象(for-in)

遍历对象   for in循环(k 是获得对象的属性名,对象名[k] 是获得属性值)
        for (let k in obj) {
            console.log(k)         // 打印属性名
            console.log(obj[k])    // 打印属性值   注意:k不能加引号,因为k是动态的
            console.log(obj['k'])  // 加引号找的是对象obj里属性名为k的值,结果为undefined
        }

for-in也可遍历数组(k代表索引值)

  • 数组 里面可以放任何的数据类型;
  • 数组名[索引值 i ]                    获取数组里的第i个元素;
  • 数组名[索引值 i ].属性名        获取数组里的第i个对象元素里的属性;
let arr = [{uname: '三剑客',age: 18,sex: '男'}, 
           {uname: '傅斯年',age: 20,sex: '女'},
           {uname: '妲己',age: 34,sex: '男'}]
for (let i = 0; i < arr.length; i++) {
    console.log(arr[0])          获取数组里的第一个元素
    console.log(arr[0].uname)    获取数组里的第一个对象元素里的属性
    console.log(arr[i])
    console.log(arr[i].uname)
}

5.内置对象(Math)

Math对象的方法 作用 举例
random 生成0-1之间的随机数 (包含0不包括1)

取 [n-m] 之间随机整数

Math.random() * (max - min + 1)) + min

ceil 向上取整(不会四舍五入)

Math.ceil(1.1) → 2

Math.ceil(1.5) → 2

floor 向下取整(不会四舍五入)

Math.floor(1.1) → 1

Math.floor(1.5) → 1

round 就近取整,四舍五入(.5往大取整)

Math.round(1.1) → 1

Math.round(1.5) → 2

Math.round(1.9) → 2

Math.round(-1.1) → -1

Math.round(-1.5) → -1

Math.round(-1.9) → -2

max 找最大数 传入的是多个数字,不是数组(利用剩余函数)

let arr = [1, 5, 9, 45]

console.log( Math.max(...arr) )

min 找最小数 Math.min(1, 5, 9, 45)
pow 幂运算

Math.pow(2,3) 8 (2的3次方)

abs 绝对值
PI

圆周率   π

随机点名

// 封装随机数函数
function getRandom(min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min
}
// 声明一个数组
let arr = ['赵云', '黄忠', '关羽', '张飞', '马超', '刘备', '曹操', 'pink老师']
// 生成1个随机数 作为数组的索引号
let random = getRandom(0, arr.length - 1)
document.write(arr[random])

随机颜色

(1)随机RGB颜色

// 封装随机RGB颜色函数
function getColor() {
    let r = Math.floor(Math.random() * 256)
    let g = Math.floor(Math.random() * 256)
    let b = Math.floor(Math.random() * 256)
    // 返回值的2种形式
    // 1. 直接返回rgb内的格式,若返回数组会比较麻烦    rgb(12,12,12)
    return `${r},${g},${b}`
    // 2. 返回数组
    // return [r,g,b]
}
// 调用函数
let color = getColor()
document.write(`
`) // document.write(`
`)

(2)随机16进制颜色

// 封装随机16进制颜色函数
function getColor() {
    // 将 0-9,a-f (可数、有索引号方便操作)放入到数组中    注意:a-f要用引号
    let arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 'a', 'b', 'c', 'd', 'e', 'f']
    let str = '#'
    // 循环6次(因为#后是6位数),筛选出6个随机数    #ffffff
    for (let i = 0; i < 6; i++) {
        // index表为索引值,索引值0-15   取[0,15]随机整数
        let index = Math.floor(Math.random() * (arr.length))  // 15+1 = 16 = arr.length
        // #与[0,15]随机整数拼接
        str += arr[index]
    }
    // 返回拼接后的字符串
    return str
}
// 调用并输出函数
let color = getColor()
console.log(color)

(3)传参返回随机RGB颜色,不传参则返回随机16进制颜色

function getColor(flag) {
    if (flag) {
        // 返回rgb颜色
    }else {
        // 返回16进制颜色
    }
}
let flag=prompt('传实参或不传实参')
getColor(flag)
/* getColor(true)
   getColor() */

(4)RGB颜色和16进制颜色之间的相互转换

猜数字游戏

// 获取随机数
let target = Math.floor(Math.random() * 10) + 1
// 确定循环次数用for循环,不确定次数用while循环
while (true) {
    let num = +prompt('请猜1~10之间的数字:')
    if (num > target) {
        alert('猜大了')
    } else if (num < target) {
        alert('猜小了')
    } else {
        alert('正确!')
        break
    }
}

WEB APIs

一、Web API 基本认知

  • JavaScript包括ECMAScript(规定语法,规范,数据类型)、webAPIs
  • Web APIs 的作用:使用 JS 去操作 html 和浏览器。Web APIs是操作 html 和浏览器的接口(方法)
  • Web APIs 包括:DOM (Document Object Model—文档对象模型,即把文档当作对象来处理,对象里有属性和方法)、BOM(浏览器对象模型)
  • DOM是开发网页内容特效和实现用户交互;BOM是操纵浏览器的
  • DOM 树(文档树):可将 HTML 文档以树状结构直观的表现出来;直观的体现了标签与标签之间的关系
  • document 是 DOM 里提供的一个对象,所以它提供的属性和方法都是用来访问和操作网页内容的(所以主要学document的方法)。网页所有内容都在document里面
  • 节点(dom对象):元素节点(对应HTML中的标签元素)、属性节点(对应HTML中的属性)、文本节点(对应HTML的标签中的内容)、注释节点

二、获取、操作DOM对象

1、获取DOM对象

语法 作用 注意
获取DOM对象 document.querySelector('选择器')  选中匹配的第一个元素,获取单个元素

选择器要加引号,不加为变量;

如果获取不到会返回null

document.querySelectorAll('选择器')

选中匹配的多个元素,获取伪数组

(要经过遍历给伪元素的项进行修改)

其它获取DOM对象的方法

document.getElementById('ID名')

document.getElementsByTagName('标签名')

伪数组

document.getElementsByClassName('类名')

伪数组

document.documentElement

获取html标签
document.body 获取body标签
id名可放在前面 id名.document.querySelector('选择器') 选中id名中符合选择器要求的第一个元素
id名.document.querySelectorAll('选择器') 选中id名中符合选择器要求的多个元素
选择器 不支持伪元素选择器,支持部分伪类选择器
  • querySelector() 方法能直接操作修改(a.style.color = 'red');querySelectorAll() 方法不能直接修改(a[2].style.color = 'red')
  • 伪数组:有长度有索引号,但是没有 pop() push() 等数组方法的数组;

2、操作元素

(1)设置/修改DOM元素内容

语法 区别 注意
对象.innerText = '修改的内容'

只识别文本,所有内容原样输出

不加=则为获取修改的内容,加=则为赋值(修改内容),不能修改表单标签

对象.innerHTML = '修改的内容'

可以解析标签

document.write()

只能将文本内容追加到 前面的位置;

文本中包含的标签会被解析

随机点名抽奖

	抽中的是:名字

	

(2)设置/修改DOM元素属性

样式 优缺点 用于
修改元素固有属性 元素.属性名 = '新属性值'

href、title、src

pic.src='路径'

修改元素样式属性 元素.style.属性名 = '新属性值' 复合属性名用小驼峰(去掉-横线,第二个单词首字母大写)

a.style.color = 'red'

用类名修改元素

(用于修改很多元素样式时)

元素.className='类名'

因为class在JS中是关键字

弊端:会覆盖原来的类名,适用于1个类名的操作

元素.classList.add='类名' 

元素.classList.remove='类名' 

元素.classList.toggle='类名' 

元素.classList.contains='类名' 

添加类名/

删除类名/

切换类名(有就删除,没有就添加)/

是否包含类名

(适用于多个类名,不影响以前类名)

修改表单元素属性 

元素.属性名 = '新属性值'

(和固有元素修改相同)

disabled   

禁用(只用于表单)

                              checkbox   

单、多选默认选中

                              selected     

下拉列表默认选中

                              readonly     只读

input.type = 'text'

inp.value = 'abc'

// disabled 禁用

   inp.disabled = true          //禁用

   inp.disabled = false        //解除禁用

   console.log(inp.disabled)    //判断是否禁用

// checked  默认选项

        inp.checked = true

        inp.checked = false

        inp.checked

随机刷图片

当我们刷新页面,页面中的图片随机显示不同的图片


	

	

3、定时器

两种定时器对比:

  • setInterval 的特征是重复执行,首次执行会延时;setTimeout 的特征是延时执行,只执行1次;
  • setTimeout 结合递归函数,能模拟 setInterval 重复执行;
  • 可以不配套使用;

(1)间歇函数

定时器(间歇函数、间歇定时器、重复性定时器)可实现 每隔一段时间需要自动执行一段代码(即,每隔一段时间调用一次函数)

1. 开启定时器     注意:函数名后不能加括号,时间是以毫秒为单位   1s=1000ms
   setInterval(函数名,时间)  	  
2. 关闭定时器     注意:必须要有定时器名字才可以清除定时器(在开启定时器时,默认返回定时器标识)
   clearInterval(定时器标识)

倒计时间案例 



	
	

轮播图案例


  
第1张图的描述信息

第1张图的描述信息

 (2)延时函数

延时函数只执行一次。

1.开启延时函数   使用规范与间歇函数相同
    setTimeout(函数,延迟的时间)
2.关闭延时函数
    clearTimeout(定时器标识)

延迟函数配合递归可模拟实现间歇定时器

递归函数:函数内部调用其自身


	
时间

三、事件

事件:用户的行为、动作(点击,双击)

1.事件

(1)事件监听

事件监听:一旦事件源被事件触发,就立即调用一个函数做出响应。

事件源.addEventListener('事件类型',函数)

事件监听的三要素:

  • 事件在哪个物体上发生(被事件触发的物体),这个物体就是事件源;
  • 事件: 用什么方式触发,比如鼠标单击 click、鼠标经过 mouseover 等;
  • 事件调用的函数: 事件源被触发后要做什么事;
  • 举例:
    
        
    
        
    

(2)事件类型

事件分类 书写 触发条件

鼠标事件

(鼠标触发)

click 单击
dblclick 双击
mouseenter 鼠标经过
mouseleave 鼠标离开
mousemove 鼠标移动
mouseup/down

焦点事件

(表单获得/失去光标)

focus 获得光标 用于表单元素
blur 失去光标

文本事件

(表单输入时触发)

input

用户输入时触发

如,textarea

change 当用户更改