循环语句
- 概念: 基于某一个条件去重复执行某一段代码,如果条件不成立,直接结束循环
- 目的: 在实际问题中,有许多具有规律性的重复操作,因此在程序中要完成这类操作就需要重复执行某些语句;
- 循环步骤:
1.初始化:就是用 var 声明的一个普通的变量,通常用于作为计数器使用;
2.进行条件判断:就是用来决定每一次循环是否继续执行就是终止的条件
3.要执行的代码
4.改变自身(改变初始化的内容):每次循环最后执行的代码,经常用于我们计数器变量进行更新(递增或者递减)
for 循环语句 (重复某些代码,通常和计数有关)
- 语法: for( 1.初始化变量; 2.条件表达式; 3.改变自身;){ 4.循环要执行的代码}
根据语法来使用 for 循环语句:
<script>
for(var n = 0; n< 3; n++){
console.log(n)
}
</script>
案例:求1~100 之间所有的和 用for 循环完成:
思路:
1.求出1~100之间所有的数字
2.求出所有数字的和
<script>
var sum = 0;
for ( var i = 1; i <= 100; i++ ) {
sum += i
}
console.log(sum)
</script>
案例:求 1~100 之间 所有 偶数的 和 用 for 循环完成;
思路:
1.求出1~100之间所有的数字
2.再求出 1~100之间所有的偶数
3.最后让所有1~100之间的 偶数进行求和
<script>
var sum = 0
for(var i =0; i <= 100;i++ ){
if(i % 2 === 0){
sum += i
}
}
console.log(sum);
</script>
while 循环语句
- 语法: while (//条件表达式){//满足条件时执行的代码}
根据语法来使用 while 循环语句:
<script>
var num = 0
while(num < 3){
console.log(1)
num++
}
执行步骤演示:
发现书写了一个 while 循环, 循环的运行条件是 num < 3,
如果后续 num 的值 不满足 这个条件的时候, 循环就会结束
否则, 一直重复执行 while 大括号内的代码
第一次执行 num === 0
while 循环的执行条件是 num < 3 目前满足, 所以进入循环开始执行内部的代码
1. console.log(1)
2. num++ ++在后先返回原值,再自+1;所以此时 num= 0;但是下一次开始执行num时num=0+1 num = 1
第二次执行 num === 1
while 循环的执行条件是 num < 3 目前满足, 所以进入循环开始执行内部的代码
1. console.log(1)
2. num++ 目前 num = 1 下次循环开始是 num = 1 + 1
第三次执行 num === 2
while 循环的执行条件 num < 3 目前满足, 所以进入循环开始执行内部的代码
1. console.log(1)
2. num++ 目前 num = 2 下次循环开始时 num = 2 + 1
第四次执行 num === 3
while 循环的 执行条件 num < 3 目前不满足条件了, 所以结束循环;
所以此时控制台 显示的是 三 个 1
</script>
案例:
需求:求出 1 ~ 100 之间的 所有数字相加的和;
思考:
首先 想办法拿到 1~100之间所有的数字;
其次 将 1~100之间所有的数字相加求和;
<script>
var num = 1
var sum = 0
while (num <= 100) {
sum += num
num++
}
console.log(sum)
执行步骤演示:
第一次执行的时候
num === 1 sum === 0
while 循环的条件是 num <= 100 此时符合条件, 所以进入循环开始执行代码
1. sum = sum + num -> sum = 0 + 1 -> sum = 1
2. num++ 改变 num 的值, 下次 num 的值就自+1了
第一轮循环到此结束
第二次执行的时候
num === 2 sum === 1
while 循环的条件 num <= 100 此时符合条件, 所以进入循环开始执行代码
1. sum = sum + num -> sum = 1 + 2 -> sum = 3
2. num++ 改变 num 的值, 下次 num 的值就自+1了
第二轮循环到此结束
第三次执行的时候
num === 3 sum === 3
while 循环的条件 num <= 100 此时符合条件, 所以进入循环开始执行代码
1. sum = sum + num -> sum = 3 + 3 -> sum = 6
2. num++ 改变 num 的值, 下次 num 的值就自+1了
第三轮循环到此结束
第四次执行的时候
num === 4 sum === 6
while 循环的条件 num <= 100 此时符合条件, 所以进入循环开始执行代码
1. sum = sum + num -> sum = 6 + 4 -> sum = 10
2. num++ 改变 num 的值, 下次 num 的值就自+1了
第四轮循环到此结束
* 第五轮
* 第六轮
* 第七轮
* 第八轮
* 第九轮
第 101 轮 就不满足条件了, 所以就不执行了
</script>
do...while 循环语句
- 语法: do{ //需要执行的代码 } while (//条件表达式)
注意: while 与 do...while 的区别:
while 循环在开始的时候,会先判断条件是否成立,然后再决定是否执行代码;如果条件不成立,直接结束循环;
do-while 循环在开始第一次的时候,不会先判断条件,也就是说,不管这个条件是否成立,它保证至少会执行一次的;
根据语法来使用 do..while 循环语句:
<script>
var num = 10
do{
console.log(num)
num--
} while (num < 5)
执行步骤演示:
第一次执行 (忽略条件,直接执行代码)
num ==== 10
因为第一次执行不需要判断条件,所以直接执行代码
console.log(num) ---> 10
num-- 下一轮使用 num 的时候,num的值就已经发生变化了,会自减1
判断条件:num<5 才能 进行下一轮循环
此时num的值是10,不满足条件,所以循环到此结束;
</script>
三元表达式:
- 概念: 有三元运算符组成的式子我们称之为三元表达式;
- 语法: 条件表达式 ? 表达式1 : 表达式2;
- 执行思路: 如果条件表达式的结果为真,则返回表达式1的值,如果条件表达式的结果为假,则返回表达式2的值;
代码体验:
<script>
var num = 1999;
var sum = num > 2000 ? '是的': '不是';
console.log(sum);
</script>
数字补0案例:实际项目中为京东秒杀倒计时;
<script>
var num = window.prompt('请您输入 0 ~59之间的数字');
var sum = num < 10 ? '0' + num : num;
document.write(sum)
</script>
流程控制语句
- 通过两个关键词,可以起到控制循环的作用,这就是流程控制;
- 通过 break 和 continue 这两种关键词:
break 关键字的应用:
- break:结束掉整个循环,不管循环后边还有几轮;
break的方法:
<script>
for (var i = 1; i<=5; i++){
console.log("我吃了一个包子")
if(i===3){
break
}
}
</script>
continue 关键字的应用:
- continue:跳出当前这一轮循环,直接开始下一轮循环
continue的方法:
<script>
for (var i = 1; i<= 5; i++){
if(i===3){
console.log("第三个包子掉地上了,我不吃这个包子了")
continue
}
console.log("我吃了一个包子")
}
</script>
循环嵌套的书写
- 概念:循环嵌套执行时,先是外层循环进行运行,条件成立,则开始运行内层循环,当内层循环全部终止运行时,则开始第二轮外部循环,当外部运行条件成立则开始运行第二遍内部循环...
<script>
for(var j = 0; j < 3; j++){
for(var i = 0; i< 3; i++){
console.log(i);
}
console.log("J输出的值为:", j);
}
0 1 2 J输出的值为: 0;
0 1 2 J输出的值为: 1;
0 1 2 J输出的值为: 2;
</script>
案例:在页面使用 * 打印 9 * 9 的方阵:
案例1:
需求: 在页面上 打印出9个 *
<script>
document.write("*")
document.write("*")
document.write("*")
document.write("*")
document.write("*")
document.write("*")
document.write("*")
document.write("*")
document.write("*")
</script>
案例2:
新需求:在页面输出一个9*9的方阵
<script>
for(var x = 0; x<9; x++){
for(var i = 0; i<9; i++){
document.write("*")
}
document.write("<br>")
}
</script>
案例:在页面使用 * 打印 三角形
需求: 在页面输出一个三角形
要求:在第一行输出1个;在第二行输出2个;在第三行输出3个;...在第九行输出9个;
<script>
for(var x = 1; x<=9; x++){
for(var i = 0; i < x; i++){
document.write("*")
}
document.write("<br>")
}
</script>
函数的概念:
- 概念; 就是封装了一段可被重复调用执行的代码块.通过此代码块可以实现大量代码的重复使用,就是多次出现的代码块封起来的盒子;
- 简单来说: JS的函数就是一个盒子,盒子里边装的是在当前页面中 多次出现的 较为复杂的代码段
函数的定义:
声明式定义:
- 语法: function 函数名(){
函数调用时要执行的代码段
}
- 注意:
注意:
function: 是声明函数的一个关键字; ->表明后续的是一段函数,必须小写;
fn : 是函数的名字; ->将来函数调用的时候需要用到,函数名自定义即可,一般是一个动词;
() 内部填写参数;
{} 内部填写函数调用时要执行的代码段
声明式定义:
<script>
function fn1(){
console.log("我是 fn1 函数:");
}
</script>
赋值式定义:
- 语法: var 变量名 = function( 填写参数){填写函数调用时要执行的代码段}
赋值式定义:
<script>
var fn2 = function (){
console.log("我是 fn2 函数:");
}
</script>
函数的调用:(函数的调用可以多次调用)
- 使用盒子内的代码
- 调用语法: 函数名()
- 注意: 函数不调用,自己不执行,也就是,如果函数只定义,没有调用,那么没有任何意义;
- 注意: 调用函数的时候千万不要忘记加()
不管是声明式还是赋值式定义的函数,调用方式都是一样的:
<script>
fn1()
fn2()
</script>
声明式与赋值式的区别:
1.写法不同;
2.调用上略有不同:
声明式定义函数,可以在函数定义前 去调用
赋值式定义函数,不能在函数定义前 去调用
赋值式定义函数不能在函数定义前调用的原因:
赋值式定义,其实就是声明了一个变量,然后给变量赋值为一个函数;
赋值式定义在JS中,如果在定义变量之前,使用变量的话,那么变量的值为 undefined;(变量提升 面试可能会问)
1.1声明式定义函数调用:
<script>
fn1()
console.log("我是 fn1函数定义前的 输出~~");
function fn1(){
console.log("我是 fn1 的函数:");
}
fn1()
fn1()
fn1()
</script>
1.2赋值式定义函数调用:
<script>
fn2()
console.log(fn2);
var fn2 = function(){
console.log("我是 fn2 函数");
}
fn2()
</script>
函数的参数
- 函数参数的作用: 能够使我们这个函数的使用更加灵活一些,不那么单一;
- 函数的形参与实参: 在声明函数时,可以在函数名称后面的小括号中添加一些参数,这些参数叫做"形参";而在调用该函数时,同样也需要传递相应的参数,这些参数叫做"实参"
形参与实参的位置:
> 形参的作用:书写之后相当于在函数内部储存一个变量,变量实际的值由"实参"传递,也就是说 形参是用来接收实参传递给它的值的;
> 实参的作用:将自身的值,按照一一对应的关系,传递给形参;
<script>
function 函数名 (形参1,形参2,形参3......){
}
函数名 (实参1,实参2,实参3......);
</script>
形参与实参的案例:
<script>
function fn(a,b){
var sum = a + b
console.log(sum);
}
fn(100,200)
</script>
函数参数的注意事项:
- 注意: 形参和实参两个参数的数量,要一一对应;
- 函数参数的个数: 可以有,也可以没有,个数上没有限制;但是必须要让形参与实参的个数上保持一致;
情况1: 形参的数量 > 实参的数量: 多余的形参定义为 undefined 结果为NaN;
<script>
function num1 (a, b, c, d){
console.log(a, b, c, d);
}
num1(66,99)
</script>
情况2:实参的数量 > 形参的数量: 那么取形参的个数
<script>
function num1 (a, b){
console.log(a, b);
}
num1(66,99,00,666,999)
</script>
函数的参数默认值:
- 函数在创建形参的时候,默认给一个值,将来在调用函数的时候,如果没有传递参数,那么这个形参的值也不会是 undefined 而是给的默认值;如果传递了对应的值,那么形参的值是市场传递进来的值,否则按照默认值来执行;
函数创建时没有给形参默认值:
<script>
function year (a,b,c,d){
console.log(a,b,c,d);
}
year()
</script>
函数创建时给形参默认值:
<script>
function year( a="我是第1个形参", b=22.222, c="我是第3个形参", d="9999" ){
console.log(a,b,c,d);
}
year()
</script>
函数的返回值(也就是函数的执行结果)return:
语法格式:
<script>
function 函数名(){
return 需要返回的结果;
}
函数名()
console.log(控制台打印结果);
</script>
(1)关键字return的出现:因为JS有一个规定:在函数内部创建(定义)的变量,只能在函数内部使用;如果想在函数外部得到函数内部的某一个值(或者运行结果),需要使用 return来帮我们实现;
(2)我们函数只是实现某种功能,最终的返回结果需要返回给函数的调用者 函数名() 通过 return 来实现
(3)只要函数遇到 return 就会把() 里的结果 返回给函数的调用者 也就是说函数名() = return 后边执行结果
return 使用案例:
需求:封装一个函数,这个函数内,需要计算50+100的值;
<script>
function fn(){
return 50 + 100
}
var num = fn()
console.log(num);
或者:
可以把: var num = fn()
console.log(num);
写成:
console.log(fn());
</script>
案例:
1. 封装一个函数, 求两个数字的最大公约数
2. 封装一个函数, 求两个数字的最小公倍数
<script>
两个数字的最大公约数:
function fn1(a,b){
var min = a>b ? b : a
for(var i = min ; i >= 1;i--){
if( a % i === 0 && b %i ===0){
return i
}
}
}
var sum = fn1(8,12)
console.log(sum);
两个数字的最小公倍数:
function fn2(a,b){
var num1= fn1(a,b)
var num2 = a*b / num1
return num2
}
var sum =fn2(8,12)
console.log(sum);
</script>
函数的预解析:
- 定义: JS在执行代码的时候,会有一个所谓的解析阶段,解析阶段,做了一件事情,就是 函数提升,就是将声明式 函数的定义,提升到当前作用的最顶端.
- 表现: 就是声明式函数在定义前可以被调用.
- 函数提升的过程:
声明式函数的正常书写:
<script>
fn()
function fn(){
console.log("我是 fn 函数,我被调用了");
}
</script>
函数提升阶段:
fn()
function fn(){
console.log("我是 fn 函数,我被调用了");
}
预解析之后的代码长什么样子?
<script>
function fn(){
console.log("我是 fn 函数,我被调用了");
}
fn()
</script>
函数的作用域
全局作用域 && 局部作用域
作用域链
访问规则
赋值规则
递归函数
写一个简单的递归
简单了解对象 Object:
- Object可以在一个变量中存储多个数据单元
- JavaScript中数组和对象的区别:
- JavaScript中 [数组] 理论上只能使用 数字 ;
- JavaScript中 [对象] 理论上只能使用 字符串 作为索引下标;
创建对象
字面量方式创建对象
- 字面量语法: var 变量 = { 属性:属性值,键名:键值对,键:值 };
内置构造函数创建
- 构造函数语法: var 变量 = new Object( { 属性:属性值,键名:键值对,键:值} );
注意: 当在控制台点击对象时,浏览器会展开显示对象存储数据;
浏览器以首字符顺序显示对象存储数据和 JS程序没有关系;
<script>
var obj1 = { name: '付美丽',age:'25',sex:'女生',addr:'北京海淀'};
var obj2 = new Object( {name: '付美丽',age:'25',sex:'女生',addr:'北京海淀'} );
console.log(obj1);
console.log(obj2);
</script>
对象内对于 键(key) 的要求:
对象数据类型的操作(增删改查)两种语法:
- 新增语法: (给对象新增数据单元,同时设定一个不存在的新的健名)
- 对象.属性 = 新增的键值对 ;
- 对象[' 属性'] = 新增的键值对;
1.新增操作:
</script>
var obj1 = {
name: '付美丽',
age:'25',
sex:'女生',
addr:'北京海淀',
};
obj1.phone = '187'
obj1['email'] = '211'
console.log(obj1);
</script>
- 修改操作:(是对已经存在的健名执行赋值操作,后赋值的数据会覆盖之前存储的数据数值,执行效果是修改数组单元存储的数据;)
- 注意: 数组中没有重复的索引下标,对象中没有重复的健名;
2. 修改操作: 给对象中已经存在的健名执行重复操作,返回覆盖后的新对象;
<script>
var obj1 = {
name: '付美丽',
age:'25',
sex:'女生',
addr:'北京海淀',
};
obj1.name = '李四'
obj1['age'] = 123
console.log(obj1);
</script>
- 注意: 删除操作一次只能删除一个对象;
<script>
var obj1 = {
name: '付美丽',
age:'25',
sex:'女生',
addr:'北京海淀',
};
delete(obj1.name);
delete(obj1['age']);
delete obj1.sex;
console.log(obj1);
</script>
点语法调用:
<script>
var obj1 = { name: '付美丽',age:'25',sex:'女生',addr:'北京海淀'};
console.log(obj1.name);
</script>
中括号调用语法(数组语法):
注意: console.log(obj1['属性值']); ->一定要加引号;
<script>
var obj1 = { name: '付美丽',age:'25',sex:'女生',addr:'北京海淀'};
console.log(obj1['name']);
</script>
两者的差异:
- 如果键名是 [ 数值类型 ]的时候, 只能使用 [ ] 语法获取, 点语法 不支持 键名是数值类型;
- 如果通过变量中存储的键名调用数据, 只能使用 [ ] 语法获取, 点语法 不支持 解析变量;
1. 实际项目中见不到这种现象
<script>
var obj1 = {
name: '付美丽',
age:'25',
sex:'女生',
addr:'北京海淀',
1:100,
2:200,
};
console.log(obj1[1]);
console.log(obj1.1);
</script>
2.变量存储健名调用
<script>
var obj1 = {
name: '付美丽',
age:'25',
sex:'女生',
addr:'北京海淀',
};
var str ='age'
console.log(obj1[str]);
console.log(obj1.str);
</script>
for in 循环专门用来遍历对象:
<script>
var obj1 = {
name: '付美丽',
age:'25',
sex:'女生',
addr:'北京海淀',
};
for( var key in obj1 ){
console.log(key, obj1[key]);
}
</script>
数组存储对象数据结构的循环遍历: ->实际项目中是数组存储对象
动态生成页面的基本思路过程:
1.从数组库获取数据,当前是定义一个数组,模拟数据库的数据;
2.循环遍历数组,数组有多少个单元就循环遍历几次,每次生成需要的html标签结构,根据数组中的数据动态生成标签内容;
3.将生成好的html标签字符串通过DOM操作,写入指定标签中;
<script>
var arr =[ { id: 1, name:"张三", age:18, sex:'男',addr:'北京'},
{ id: 2, name:"张三", age:19, sex:'男',addr:'北京'},
{ id: 3, name:"张三", age:20, sex:'男',addr:'北京'},
{ id: 4, name:"张三", age:21, sex:'男',addr:'北京'},
{ id: 5, name:"张三", age:22, sex:'男',addr:'北京'},
{ id: 6, name:"张三", age:23, sex:'保密',addr:'北京'} ]
var str = '';
for(var i = 0; i <= arr.length-1; i++){
str += ` <tr>
<td>${arr[i].id}</td> //模板字符串支持换行;
<td>${arr[i].name}</td>
<td>${arr[i].age}</td>
<td>${arr[i].sex}</td>
<td>${arr[i].addr}</td>
</tr>`
console.log(str)
}
const oTbody = document.querySelector('tbody')
oTbody.innerHTML = str
document.write(str);
</script>
包装类型字符串:
- 字符串类型也支持 [ ]语法 和length属性;
- 可以通过length属性获取字符串长度;
- 可以通过 [ ]语法设定索引下标来操作对应的某个字符
字符串执行length属性调用:
<script>
var str = 'abcdefg';
console.log(str.length);
</script>
字符串执行[ ]方括号语法:
<script>
var str = 'abcdefg';
console.log(str[0]);
console.log(str[1]);
console.log(str[2]);
console.log(str[3]);
console.log(str[4]);
console.log(str[5]);
</script>
- for循环方法:
- for..in方法:
- for..of方法:
- foeEach方法: 只能循环数组 不能循环字符串;
通过for循环生成字符串的索引下标
<script>
for(var i = 0; i <=str.length-1; i++){
console.log(str[i]);
}
</script>
for...in方法:
<script>
for( var index in str){
console.log(index,str[i]);
}
</script>
for...of 方法:
<script>
for(var value of str){
console.log(value);
}
</script>
获取随机字符
- 在JavaScrit程序中,有专门生成随机数值的函数方法
- Math.random() 它随机生成 0 ~ 1的小数,可以是 0不会是 1;
- 如果要生成数值1 和 数值2范围的随机数字:
- 公式: parseInt( Math.random() * (数值2 +1-数值1) +数值1);
<script>
var str = 'abcdefg' ;
console.log( Math.random() );
var index = parseInt( Math.random() * str.length ) ;
console.log( index );
console.log( str[ index ] );
</script>
字符串函数查询:
- 作用: 查询字符串中有没有当前字符
- 返回值:如果有当前字符,则返回该字符串中第一个字符的索引下标; 如果没有当前字符,则返回值是-1 ;
- 字符串.lastIndexOf('要查找的字符')
- 作用:查询字符串中有没有当前字符
- 返回值:如果有当前字符则返回该字符串该字符最后一次出现的索引下标;如果没有当前字符,则返回是-1
代码示范:
<sceipt>
var str = 'abcdcefgh';
console.log(str.indexOf( 'c')/查询字符 'c' ,返回值是第一个 c 的索引下标;
console.log(str.indexOf( 'B' ));//查询字符 'B' ,因为字符中没有B,所以返回值是 -1;
console.log(str.lastIndexOf( 'c'));//查询字符 'c' ,返回值是最后一个 c 的索引下标;
console.log(str.lastIndexOf( 'B'));//查询字符 'B' ,因为字符中没有B,所以返回值是 -1;
</sceipt>
需求: 生成6位验证码
思路: 写一个字符串存储所有的字符内容
每次生成一个随机索引下标,再获取一个随机字符,拼接到验证码字符串中,需要几位验证码就循环几次;
<script>
var str = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
var vcStr = '';
for (var i = 1; i <= 6; i++) {
var index = parseInt(Math.random() * str.length);
vcStr += str[index];
}
console.log( vcStr );
</script>