【JS流程控制】最需有逻辑思维部分,独立写不出来项目很可能是这块出了问题

1,320 阅读18分钟

前言


你盼世界,我盼你永不脱发。Hello 大家好!我是啊华!

前几周加入掘金,输出了几篇文章,但是文章形式更像笔记。这段时间看了很多掘金上优秀作者的文章,和自己的相比。我自愧不如呀!自己仔细思考了一下,后面写文章还是要更注重质量,让读者可以通俗易懂,自己所学输出也能帮助到其他正在学习前端的朋友们。

程序最重要的就是逻辑思维,很多小伙伴在学习前端的时候,学完感觉自己独立做项目做不出来,如果看视频的话又感觉都可以听懂。我之前也是这样,我之前甚至怀疑自己是不是不适合学习编程。其实不并不是不适合,最主要的原因还是自己的基础打的不牢靠,流程控制这一块没掌握好

废话不多说(虽然已经说了很多废话了),哈哈😁,开始干货,相信看完这篇,流程控制这一块你肯定没问题了!让我们看看通过这一章节的阅读你能学习到什么:

  • 流程图的绘制
  • if判断
  • switch
  • for循环
  • while循环
  • do while循环
  • breakcontinue
  • 数组以及应用

流程图的绘制

  • 什么是流程图呢?

一套的标准的图形,用于描述程序的逻辑。

  • 我们为什么会使用到流程图呢?

通常流程图分析程序的流程 (如果程序比较复杂,那么可以用流程图来分析),有了流程图那么我们分析一些逻辑问题就会简单很多了。

  • 在markdown中画流程图

通过一个图,给大家看一下语法分别代表的含义

  1. 开始和结束一般用圆,来表示,在流程中语法是 start((开始))ed((结束))

  2. 绘制方向: 语法 graph TD 意思是从上到下开始绘制流程图

  3. 判断: 语法:{} ,判断写到里面

  4. 流程过程::语法[],流程写到里面

  5. 指向:语法-->,判断如果为真,那么会执行哪一步,如果为假会指向那个流程。

上面的流程图画出来是这个样式的:

我们来举一个经典的买桃子和卖西瓜的例子。A给B说,去买俩个桃子吧,如果遇到卖西瓜的话就买一个,用流程图画出来。

A的思维: 流程图展示: B的思维: 流程图展示: 以上是流程图画法,有时候还是挺重要的,可以自己亲自试验一波。这里了解一下就可以了。

if判断

if判断,是JavaScript中第一个接触到逻辑的地方,后面做项目中的条件判断少不了它,不过它很简单。我们来看一下他的语法和写法。

例如:

if(条件1){ // 条件会进行布尔判定,为真会执行下面代码块的内容,为假直接不执行。 如果条件1为真,那么后面的else if 和 else都不执行。如果为假 那么就会继续往后看其他条件,为真就停止看后面的条件。
    // 代码块
}
else if(条件2){
    // 代码块
}
else if(条件3){
    // 代码块
}
//....
else{
    // 以上条件都不满足执行的代码块
}
  • 注意点
  1. 如果某个条件满足,则直接忽略后面的所有条件(不执行)

例如:

        var score = 95;
        // A:>=90  B: >=70 <90  C: >=50 <70  D: <50
        //代码简化版
        if (score >= 90) {
            console.log("A");
        } else if (score >= 70) {
        //当进行到这个条件的时候,说明第一个不满足score<90。相当于:score >= 70 && score < 90
            console.log("B");
        } else if (score >= 50) {
            console.log("C");
        } else {
            console.log("D");
        }
        //非简化版本
        if (score >= 90) {
            console.log("A");
        } else if (score >= 70 && score < 90) {
            console.log("B");
        } else if (score >= 50 && score < 70) {
            console.log("C");
        } else {
            console.log("D");
        }
  1. else if 可以有多个(包含0个)
  2. else可以有1个或0个
  3. else可以换行,可以不换行
  4. 如果代码块只有一条语句,可以省略花括号(不推荐)
  5. if只能出现一次 (if 和 else if执行的区别)多个if影响执行效率,因为都执行

例如:

 if (score >= 90) {
           console.log("A");
         }
         if (score >= 70 && score < 90) {
          console.log("B");
       }
       if (score >= 50 && score < 70) {
            console.log("C");
         }
         if (score < 50) {
             console.log("D");
         }
        // 多个if的话,每个if都要执行。 如果是else if 的话,第一个为真的后,后面就直接不看不执行

例如:

        if (!x) {
            x = 0;
        }
        if (x++ >= 1) {
            var x; // 不论条件是否满足,都会发生变量生命提升
            x++;
        } else if (++x >= 2) {
            x++;
        } else {
            x--;
        }
        console.log(x); // 3

针对于if判断这一块理论知识点就这么多了,下面我们来看一些针对这一块的练习题。光学不练,等于白费。话不多说,上题。

  • if判断习题
  1. 让用户输入一个数字,如果点击了取消,输出取消,如果点击了确定,根据输入的内容判断输入是否正确
 // 等待用户操作(确定,取消),将用户操作的结果保存到变量result中
 var result = prompt("请输入你的年龄");
        if (result === null) { 
// 为什么用 === 不用 ==   如果 == 的话 会发生转化,result为0的时候,null转化为0 ,也是相等。就会发生错误。 ===必须是值和类型都完全相同。
            console.log("点击了取消");
        } else {
            // result = +result; //转换为数字
            if (isNaN(+result) || result === '') {
                //不是正常的数字
                console.log("输入有误");
            } else {
                console.log(result, typeof result);
            }
        }
  1. 提示用户输入一个三位数,若不是三位数,则提示用户输入有误;若是三位数,则判断该数能否被13整除。
        var number = +prompt("请输入一个三位数");
        if (isNaN(number) || number < 100 || number > 999) {
            console.log("输入有误");
        } else {
            if (number % 13 === 0) {
                console.log("能被13整除")
            } else {
                console.log("不能被13整除")
            }
        }
  1. 让用户输入一个成绩(0-100),判断这个成绩属于哪个范围并输出结果(A:90-100 B:70-89 C:60-69 D:40-59 E:0-39),若用户输入的不是0-100的数字,则输出输入有误。
        var score = +prompt("请输入一个成绩(0~100)");
        if (isNaN(score) || score < 0 || score > 100) {
            console.log("输入有误");
        } else {
            if (score >= 90) {
                console.log("A")
            } else if (score >= 70) {
                console.log("B")
            } else if (score >= 60) {
                console.log("C")
            } else if (score >= 40) {
                console.log("D")
            } else {
                console.log("E");
            }
        }
  1. 根据世界卫生组织推荐的计算方法,

男性标准体重计算方法为(身高cm-80)×70﹪

女性标准体重计算方法为(身高cm-70)×60﹪

标准体重正负10%为正常体重,低于标准体重的10%为过瘦,高于标准体重的10%为过重

编写程序,让用户输入性别、身高、体重,判断用户的健康状况

健康状况有3种:

  1. 你的体重正常,请继续保持
  2. 你的身体偏瘦,请加强营养
  3. 你的身体偏胖,请加强锻炼
        var height = +prompt("请输入身高(cm)");
        var weight = +prompt("请输入体重(kg)");
        var gender = prompt("请输入性别(男,女)");
        if (isNaN(height) || isNaN(weight) || gender !== "男" && gender !== "女") {
            console.log("输入有误");
        } else {
            var standardWeight; //标准体重
            if (gender === "男") {
                standardWeight = (height - 80) * 0.7;
            } else {
                standardWeight = (height - 70) * 0.6;
            }

            if (weight < standardWeight * 0.9) {
                console.log("你的身体偏瘦,请加强营养");
            } else if (weight > standardWeight * 1.1) {
                console.log("你的身体偏胖,请加强锻炼")
            } else {
                console.log("你的体重正常,请继续保持");
            }
        }
  1. 某理财公司推出一种理财服务,服务规则如下:

若用户的理财金额在50万元以下,则每年的收益按照4%计算。

若用户的理财金额在50万元以上(包括50万),则每年收益按照4.5%计算。

若用户的理财金额超过200万,除了理财收益外,还要额外给予用户收益金额的10%

编写程序,让用户输入理财金额和理财年限,计算到期后的收益

        var money = +prompt("请输入理财金额");
        var year = +prompt("请输入理财年限");
        if (isNaN(money) || isNaN(year) || money <= 0 || year <= 0) {
            console.log("输入有误");
        } else {
            var rate = 0.04; // 年利率4%
            if (money >= 500000) {
                rate = 0.045;
            }
            var earnMoney = money * rate * year; // 收益
            if (money >= 2000000) {
                earnMoney += earnMoney * 0.1;
            }
            console.log(`总收益为:${earnMoney}`);
        }
  1. 编写一个用户和计算机猜拳的游戏,用户输入剪刀、石头或布,与计算机的出拳进行比较,判断胜负
        var fist = prompt("请出拳(剪刀、石头、布)");
        if (fist === "剪刀" || fist === "石头" || fist === "布") {
            //正确
            //1. 模拟计算机出拳
            var rad = Math.random(); // 0~1
            var pcFist; //计算机出拳结果
            if (rad < 0.333) {
                pcFist = "剪刀";
            } else if (rad < 0.6666) {
                pcFist = "石头";
            } else {
                pcFist = "布";
            }
            //2. 比较胜负
            console.log(`你的出拳:${fist}, 电脑出拳:${pcFist}`);
            if (fist === "剪刀" && pcFist === "布" ||
                fist === "布" && pcFist === "石头" ||
                fist === "石头" && pcFist === "剪刀") {
                console.log("你胜利了!");
            } else if (fist === pcFist) {
                console.log("平局");
            } else {
                console.log("电脑胜利!");
            }
        } else {
            console.log("输入有误")
        }

        // if (fist !== "剪刀" && fist !== "石头" && fist !== "布") {
        //     console.log("输入有误")
        // } else {
        //     //正常
        // }

switch开关

switch的语法始终可以使用if结构替代。

switch(表达式){
    case 数据1:
        代码块
    case 数据2:
        代码块
    //...
    default:
        代码块
}
  1. 计算表达式的返回值,依次和case后面的数据进行严格相等的比较, 如果某个相等,停止比较,然后运行其内部的代码块,再然后,依次运行之后的所有代码块。
  2. 在case分支内部,使用break语句,可以立即停止switch结构。遇到break后面的代码直接不switch后面的case直接不运行
  3. default表示前面的所有case都不匹配时运行。可以省略

例:

        var x = 20;
        switch (x) {
            case 1:
                console.log("1");
                break;
            case 20:
                console.log("20");
                break;
            case 30:
                console.log("30");
                break;
            default:
                console.log("default");
                break;
        }

循环

  • 什么是循环?作用是什么?

重复的运行一段代码

JS支持3种循环结构:while循环、do-while循环、for循环

  1. while循环
while(条件){
    代码块(循环体)
}

用流程图来解释一下更加的清楚,哈哈,这时候流程图就派上用场啦。 例:输出100个hello world

  console.log("hello world");
  var i = 0; //当前输出的次数,初始化
  while(i < 100){
      console.log("hello world");
       i++;
         }

死循环:条件永远满足,永远无法退出循环。

        for (var i = 0; i < 100; i++) {
            console.log("hello world");
        }

        console.log("循环结束", i);
  1. do-while循环
do{
    循环体
} while(条件);

do-while至少运行一次。 while循环条件不满足一次都不运行

例:

        // 输出100个hello world
        // console.log("hello world");
        var i = 0; //当前输出的次数
        do {
            console.log("hello world");
            i++;
        } while (i < 100);
        console.log("循环结束");

for循环

for(初始化表达式; 条件; 条件改变表达式){
    循环体
}
``````js
for(初始化表达式; 条件; 条件改变表达式){
    循环体
}

注意for循环中 i++的位置,可以在括号中,在括号中代表continue跳出后,i++还会执行。 如果写在代码块中要根据关键字进行判断是否还会执行i++;在括号内的i++,在执行完当前循环后,i++一定会最后执行,无论是否有continue

例:

        // 输出 1-100 的所有数字
        for (var i = 1; i <= 100; i++) {
            // 在循环体中,i的值从1变化到100
            console.log(i);
        }

        输出 100-1 的所有数字
        for (var i = 100; i >= 1; i--) {
            console.log(i);
        }

        输出 1-100 的所有奇数
        for (var i = 1; i <= 100; i++) {
            // 判断i是不是奇数
            if (i % 2 !== 0) {
                console.log(i);
            }
        }

        for (var i = 1; i <= 100; i += 2) {
            console.log(i);
        }

break和continue

循环控制语句

  1. break; 跳出循环 break后面 循环代码块中的代码直接不执行直接跳出循环,执行循环后的代码
  2. continue; 停止当前循环体,进入下一次循环。 遇到continue,结束当前循环,循环代码块后面的代码不看,直接跳到下一次循环

下面的题目我故意打了注释,大家可以依次看一下代码运行后的结果。如果这些都可以做对,那么循环这一块掌握的基本上没什么问题了。

例:

        // var i = 0;
        // while (i < 10) {
        //     console.log(i);
        //     if (i === 3) {
        //         break;
        //     }
        //     i++;
        // }
        // console.log("循环结束", i); 

        // var i = 0;
        // while (i < 10) {
        //     console.log(i);
        //     if (i === 3) {
        //         continue;
        //     }
        //     i++;
        // }
        // console.log("循环结束", i);

        // var i = 0;
        // while (i < 10) {
        //     if (i === 3) {
        //         i++;
        //         continue;
        //     }
        //     console.log(i);
        //     i++;
        // }

        // for (var i = 0; i < 10; i++) {
        //     if (i === 3) {
        //         continue;
        //     }
        //     console.log(i);
        // }

        // console.log("循环结束", i);

        // for (var i = 0; i < 10;) {
        //     if (i === 3) {
        //         continue;
        //     }
        //     console.log(i);
        //     i++;
        // }
        // console.log("循环结束", i);


        // for (var i = 0; i < 3; i++) {
        //     for (var j = 0; j < 3; j++) {
        //         console.log(i, j);
        //         if (i + j >= 2) {
        //             break;
        //         }
        //     }
        // }

循环应用

  1. 累计

举例:将1-100的所有数字相加之和

思路:准备一个变量,初始值为0,然后1-100循环,每次循环,将数字累加到变量中。

例:

        // 1-100 数字相加
        // var sum = 0; //最终的和
        // for (var i = 1; i <= 100; i++) {
        //     sum += i;
        // }
        // console.log(sum);

        // 1-10 数字相乘
        // var sum = 1;
        // for (var i = 1; i <= 10; i++) {
        //     sum *= i;
        // }
        // console.log(sum);

        // 1-100 所有奇数相加
        var sum = 0;
        for (var i = 1; i <= 100; i++) {
            if (i % 2 !== 0) {
                sum += i;
            }
        }
        console.log(sum);
  1. 查找

举例:135~145之间是否存在能整除26的数字

思路:准备一个变量,记录false,表示没有找到,然后135-145进行循环,如果发现满足条件的数字,重新记录变量为true,表示找到了,然后退出循环。

例:

        // 135-145 之间是否存在 能整除26的数字
        // var isFind = false; //是否找到
        // var min = 135,
        //     max = 145;
        // for (var i = min; i <= max; i++) {
        //     if (i % 26 === 0) {
        //         isFind = true;
        //         break;
        //     }
        // }
        // if (isFind) {
        //     console.log("存在");
        // } else {
        //     console.log("不存在");
        // }

        // 打印135-185之间所有能整除26的数字
        // for (var i = 135; i <= 185; i++) {
        //     if (i % 26 === 0) {
        //         console.log(i);
        //     }
        // }

        // 打印135-185之间第一个能整除26的数字,如果不存在,输出不存在
        // var isFind = false;
        // for (var i = 135; i <= 185; i++) {
        //     if (i % 26 === 0) {
        //         console.log(i);
        //         isFind = true;
        //         break;
        //     }
        // }
        // if (!isFind) {
        //     console.log("不存在");
        // }

        // 判断一个数是不是素数(质数)
        // 素数:一个大于1的整数,只能被1和自身整除
        // 比如:2是一个素数
        // 比如:4不是一个素数
        // 思路:从1循环到这个数,记录有多少个数字能整除它,

        // var num = 1;
        // var isFind = false; //没有找到
        // for (var i = 2; i < num - 1; i++) {
        //     if (num % i === 0) {
        //         isFind = true;
        //         break;
        //     }
        // }
        // if (num <= 1 || isFind) {
        //     console.log("不是素数");
        // } else {
        //     console.log("是素数");
        // }


        // var record = 0; //记录整除数量
        // for (var i = 1; i <= num; i++) {
        //     if (num % i === 0) {
        //         record++;
        //     }
        // }
        // if (record === 2) {
        //     console.log("是素数")
        // } else {
        //     console.log("不是素数");
        // }
  1. 嵌套的循环

分开分析两层循环

        // 打印1-100的所有素数
        for (var i = 1; i <= 100; i++) {
            // 判断i是不是素数
            var isFind = false; //没有找到
            for (var j = 2; j < i - 1; j++) {
                if (i % j === 0) {
                    isFind = true;
                    break;
                }
            }
            if (i > 1 && !isFind) {
                console.log(i);
            }
        }

数组

数组用于存放多个数据

  • 创建一个数组
  1. new Array(长度)

长度,数组里面的数据总数,长度一定是一个非负整数

new Array(数据, 数据, 数据....)

创建一个数组,并初始化其每一项的值

数组项:数组其中的一项数据

  1. [数据,数据,数据,....]

创建一个数组,并初始化其每一项的值

数组当中的数据可以是任意类型的,数字,字符串,对象等。。

  • 认识数组的本质

数组的本质是一个对象

  1. length属性:数组的长度,会自动变化,值为最大下标+1
  2. 数字字符串属性:叫做下标,也叫做索引,相当于数组中每个数据的编号,下标从0开始排列
// 如果直接给数组长度属性一个非常大的值arr[10],那么没有这些索引的,就有多少个空数据。
var arr = [1,2];
arr[10] = 1;
//那么 arr[2] -- arr[9] 都是空数据

连续下标的取值范围:0 ~ length -1,如果给length直接赋值,会导致数组可能被截断

var arr = [1,2,3,4,5,6];
arr.length = 3; 
// 那就会截断数组变为[1,2,3];

// 如果 
arr.length = 10;
// 那么arr[6] - arr[9]那会为空数据

实际开发中,不要给length赋值。

  • 下标

通常情况下,下标是连续的。

下标不连续的数组,叫做稀松数组。

数组的常见操作

  1. 添加数组项
  1. 数组[长度] = 数据:向数组末尾添加一个数据 数组.push(数据): 向数组末尾添加一个数据
  2. 数组.unshift(数据):向数组起始位置添加一个数据,会导致数组每一项的下标向后移动
  3. 数组.splice(下标, 0, 添加的数据): 从指定下标位置开始,删除0个,然后在该位置插入添加的数据,如果下标超过范围,则按照范围的边界进行处理。

如: 数组里面有3项,splice下标为100,那么会在数组最后数组下标3,4,加数据。不会形成稀松数组。 如果下标为-234 负数的话,那么 就是 下标0出加数据,后面的下标顺延,不会形成稀松数组

push、unshift、splice可以添加多个数据

  1. 删除数据
  1. delete 数组[下标]: 这种做法不会导致数组其他的属性(下标 和 length 都不变)发生变化,因此,该做法会导致产生稀松数组,所以不推荐使用该做法。
  2. 数组.pop(): 删除数组的最后一项,该表达式返回最后一项的数据
  3. 数组.shift():删除数组第一项,该表达式返回第一项的数据
  4. 数组.splice(下标, 删除的数量, 添加的数据): 从指定下标位置开始,删除指定数量,然后在该位置插入添加的数据,如果下标超过范围,则按照范围的边界进行处理。返回一个新数组,该数组记录被删除的数据。
  1. 其他操作
  1. 数组.slice(起始位置下标, 结束位置下标):将起始位置到结束位置之间的数据拿出来,得到一个新的数组,该函数不会改变原数组;注意:结束下标取不到

如果什么都不写,代表截取整个数组并且返回 数组.slice()

下标可以写负数,如果是负数,则从数组的末尾开始计算。 倒数第一位是 -1。

如果不写结束下标,则直接取到末尾。

  1. 数组清空

数组.splice(0, 数组.length);

数组.length = 0;

  1. 查找数组中某一项的下标

数组.indexOf(数据)

从数组中依次查找对应的数据,查找时使用严格相等进行比较。找到第一个匹配的下标,返回。如果没有找到,则得到-1;

数组.lastIndexOf(数据)

功能和indexOf类似,只是查找的是最后一个匹配的下标

  1. 数组.fill

数组.fill(数据):将数组的所有项,填充为指定的数据

数组.fill(数据, 开始下标): 将数组从开始下标起,到数组的末尾,填充为指定的数据

数组.fill(数据, 开始下标,结束下标): 将数组从开始下标起,到数组的结束下标(取不到),填充为指定的数据

  1. 数组.jion(分隔符):返回一个字符串。不改变原数组。

  2. 数组1.contact(数组2): 将数组2中的所有元素拼接到数组1的末尾。会返回一个新的数组,不会改变原数组。

in关键字

判断某个属性在对象中是否存在 返回类型 Boolean

属性名 in 对象

for-in foreach 循环

for(var prop in 对象){
    //循环体
}

取出对象的所有属性名,每次循环将其中一个属性名赋值给变量prop,运行循环体。

  • for in 循环遍历数组和for循环遍历数组的区别

区别在与稀松数组,for循环对于没有的索引下标也会遍历,输出undefined。 for in不会,他是根据属性名遍历的

这一块我将数组放在流程控制的原因是循环和数组经常会结合到一块去应用,面试题也经常这样出。

后语


你盼世界, 我盼望你永不脱发。这篇文章就介绍到这里了,希望大家可以掌握流程控制这块内容,面试写项目得心应手。

最后,码字不易,点个赞再走呗 😊 ~

建议点赞收藏。哈哈哈,有补充的地方欢迎大家评论补充哈。

我会不定时的更新一些前端方面的知识内容以及自己的原创文章🎉

你的鼓励就是我持续创作的主要动力 😊.

本文使用 mdnice 排版