JavaScript进阶(一)(循环,数组,变量,函数提升)

本文详细介绍了JavaScript的基础知识,包括流程控制(顺序、分支、循环),if语句的多种形式,三元表达式,switch语句的使用。接着讲解了循环结构,如for循环和while循环,以及do...while循环,同时涉及continue和break关键字。此外,还深入探讨了数组的创建、访问、遍历和操作。函数的声明、调用、参数、返回值和作用域也有所阐述,特别是arguments对象的使用。最后,文章讨论了JavaScript的预解析机制,包括变量和函数的提升。

1.流程控制

顺序结构,分支结构,循环结构

2.if的语法结构

2.1 if

 <script>
    if (条件表达式) {

      //可执行代码块
    }
  </script>

2.2 if...else

  <script>
    if(条件){
      可执行代码块
    }else{
      可执行代码块
    }
  </script>

2.3 if...else..if

<script>
    if (条件1) {
      代码1
    } else if (条件2) {
      代码2
    } else if (条件3) {
      代码3
    } else {
      代码4
    }
  </script>

3.三元表达式

定义:由三元运算符组成的式子

语法结构:条件表达式?表达式1:表达式2

如果条件表达式为真,则返回表达式1,如果条件表达式为假,则返回表达式2的值

三元表达式的返回值要赋值给一个变量

<script>
    var number = 10;
    var result = number > 5 ? true : false;
    console.log(result);//true
  </script>

数字补零案例

 <script>
    var num = prompt('请输入数字');
    var result = num < 10 ? '0' + num : num;
    console.log(num);

  </script>

4 switch语句

语法结构:表达式和case的值进行匹配,必须是全等,值和类型都相同,注意没有break时。默认为continue

  <script>
    switch (表达式) {
      case value1:
        执行语句1
        break;
      case value2:
        执行语句2;
        break;
     ...
        default:
        执行最后的语句
    }
  </script>

代码示例

<script>
    var num = Number(prompt("请输入0-4之间的数字"));
    switch (num) {
      case 1:
        alert("您输入了" + num);
        break;
      case 2:
        alert("您输入了" + num);
        break;
      case 3:
        alert("您输入了" + num);
        break;
      case 4:
        alert("您输入了" + num);
        break;
      default:
        alert('输入错误');
    }
  </script>

5.循环结构

5.1 for循环

语法结构

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

示例

<script>
    for (var i = 0; i < 10; i++) {
      console.log(i);
    }
  </script>

断点调试

 双重for循环,外层循环一次,内层循环全部

 <script>
    for (var i = 0; i <= 3; i++) {
      console.log('外层循环第' + i + '次')
      for (var j = i; j <= 3; j++) {
        // str = str + '* ';
        console.log('内层循环第' + j + '次')
      }
    }
  </script>

6.while循环

6.1语法格式

 <script>
    while (条件表达式) {
      //循环体
    }
  </script>

示例1(注意防止死循环)

  <script>
    var num = 1;
    while (num < 10) {
      console.log('hhh');
      num++;
    }
  </script>

示例2

 <script>
    var age = 1;
    while (age <= 100) {
      console.log("今年" + age + "岁了");
      age++;
    }
  </script>

示例3

<script>
    var i = 1;
    var total = 0;
    while (i <= 100) {
      total += i;
      i++;
    }
    console.log(total);
  </script>

6.2 do...while循环

语法格式

 <script>
    do {
      //循环体
    } while{ 条件表达式 }
  </script>

先执行循环体,再判断条件,至少执行一次

示例

 <script>
    var i = 0;
    do {
      console.log(i);
      i++;
    } while (i <= 100)
  </script>

不满足条件,以下代码只执行一次

<script>
    var i = 0;
    do {
      console.log(i);
      i++;
    } while (i <= - 100)
  </script>

7.continue关键字

立即跳出本次循环,继续下一次循环

<script>
    for (var i = 0; i <= 5; i++) {
      if (i == 2) {
        continue;
      }
      console.log(i)//0,1,3,4,5  跳过2
    }
  </script>

8.break关键字,终止循环

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

9.数组

9.1 定义:把一组相关的数据一起存放,并提供方便的访问方式

9.2 数组的创建方式

(1)利用new创建数组

 <script>
    var 数组名 = new Array();
    var arr = new Array();
  </script>

(2)利用字面量[]创建数组

 var 数组名 = [];
    var arr = [1, 2, 3, 4, 6];

数组中可以存放任意数据类型

9.3访问数组元素

(1)数组索引(索引从0开始)

数组名[元素索引]

  <script>
    var arr = ['桃子', '苹果', '橘子', '梨子'];
    console.log(arr);//(4) ['桃子', '苹果', '橘子', '梨子']
    console.log(arr[1]);//苹果
    console.log(arr[2]);
    console.log(arr[3]);
  </script>

(2)遍历数组

用for循环遍历

  <script>
    var arr = ['桃子', '苹果', '橘子', '梨子'];
    console.log(arr);//(4) ['桃子', '苹果', '橘子', '梨子']
    for (var i = 0; i < 4; i++) {
      console.log(arr[i]);
    }
  </script>

(3)数字长度

数组名.length

 <script>
    var arr = ['桃子', '苹果', '橘子', '梨子'];
    console.log(arr);//(4) ['桃子', '苹果', '橘子', '梨子']
    for (var i = 0; i < arr.length; i++) {
      console.log(arr[i]);
    }
  </script>

示例1 计算数组的和以及平均值

 <script>
    var arr = [1, 3, 5, 2, 4, 12, 67];
    var total = 0;
    var avg = 0;
    for (var i = 0; i < arr.length; i++) {
      total = total + arr[i];
      avg = total / arr.length;
    }
    console.log(total);
    console.log(avg)
  </script>

示例2 求数组最大值,最小值

  <script>
    var arr = [2, 6, 1, 77, 52, 25, 7, 908];
    var min = arr[0];
    var max = arr[0];
    for (var i = 0; i < arr.length; i++) {
      if (arr[i] < min) {
        min = arr[i]
      }
      if (arr[i] > max) {
        max = arr[i];
      }
    }
    console.log(min);
    console.log(max);
  </script>

示例2:数组转换为字符串变量

<script>
    var str = '';
    var arr = ['red', 'green', 'blue', 'pink'];
    for (var i = 0; i < arr.length; i++) {
      str += arr[i] + '|';
    }
    console.log(str);//red|green|blue|pink|
  </script>

(4)数组中新增元素

【1】修改length长度新增数组元素

 <script>
    var arr = [1, 2];
    console.log(arr.length);//2
    arr.length = 5;
    //数组扩容,不存在的元素默认为undefined
    console.log(arr);// [1, 2, 空属性 × 3]
    console.log(arr[2]);//undefined
    console.log(arr[3]);//undefined
    console.log(arr[4]);//undefined
    //为追加的元素赋值
    arr[2] = 8;
    console.log(arr[2]);//8
    //替换元素
    arr[0] = 89;
    console.log(arr[0])//89
  </script>

示例:将1-10放进数组中

 <script>
    var arr = [];
    for (var i = 0; i <= 9; i++) {
      arr[i] = i + 1;
    }
    console.log(arr);
  </script>

示例:筛选数组元素

 <script>
    arr1 = [];
    var j = 0;//引入新变量,防止数组元素被覆盖
    var arr = [2, 0, 6, 1, 77, 0, 52, 0, 25, 7];
    for (var i = 0; i < arr.length; i++) {
      if (arr[i] >= 10) {
        arr1[j] = arr[i];
        j++;
      }
    }
    console.log(arr1);

  </script>

方法2

  <script>
    arr1 = [];
    var arr = [2, 0, 6, 1, 77, 0, 52, 0, 25, 7];
    for (var i = 0; i < arr.length; i++) {
      if (arr[i] >= 10) {
        arr1[arr1.length] = arr[i];
      }
    }
    console.log(arr1)
  </script>

 筛选出不是0的数组

 <script>
    var arr = [2, 0, 6, 1, 77, 0, 52, 0, 25, 7];
    arr1 = [];
    for (var i = 0; i < arr.length; i++) {
      if (arr[i] != 0) {
        arr1[arr1.length] = arr[i]
      }
    }
    console.log(arr1);
  </script>

反转数组

 <script>
    var arr = [2, 0, 6, 1, 77, 0, 52, 0, 25, 7];
    arr1 = [];
    for (var i = 0; i < arr.length; i++) {
      arr1[arr1.length] = arr[arr.length - i - 1];
    }
    console.log(arr1);
  </script>

数组排序(冒泡排序)

主要通过2层循环,外层循环负责循环次数,内层循环负责变量交换次数,然后在内层循环内,比较并交换两个元素的顺序

  <script>
    var arr = [2, 0, 6, 1, 77, 0, 52, 0, 25, 7];
    for (var i = 0; i <= arr.length - 1; i++) {
      //外层循环管趟数
      for (var j = 0; j <= arr.length - i; j++) {
        //内层循环的次数,管交换次数
        //内部交换两个变量,前一个和后一个比较
        if (arr[j] > arr[j + 1]) {
          var temp = arr[j];
          arr[j] = arr[j + 1];
          arr[j + 1] = temp;
        }
      }
    }
    console.log(arr);
  </script>

10 函数

函数的使用

10.1.声明函数

function 函数名(){
函数体
}

10.2.调用函数

函数名()

案例

<script>
    function getSum(num1, num2) {
      var total = 0;
      for (var i = num1; i <= num2; i++) {
        total += i;
      }
      console.log(total)
    }
    getSum(1, 3);
  </script>

10.3.函数的参数

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

}
函数名(实参1,实参2,...)

形参类似于变量,用来接收实参

形参可以视为不用声明的变量,不传值默认为undefined

函数的参数可以有,可以没有,个数不限

10.4.函数的形参和实参个数不匹配的问题

10.4.1 形参数量多于实参,返回NaN

  <script>
    function getNum(num1, num2, num3) {
      var sum = 0;
      sum = num1 + num2;
      console.log(sum)
    }
    getNum(1);//NaN

  </script>

10.4.2 形参数量少于实参数量,多于形参的实参不参与运算

  <script>
    function getNum(num1, num2, num3) {
      var sum = 0;
      sum = num1 + num2 + num3;
      console.log(sum)
    }
    getNum(1, 2, 9, 4);//12   只有1,2,9参与运算
  </script>

10.4.3 形参数量和实参相同,正常输出

10.5 函数的返回值

return将函数的结果返回给调用者

function 函数名(){
return 需要返回的结果
}
函数名()
<script>
    function getResult(a, b) {
      return a + b;
    }
    var res = getResult(1, 2);
    console.log(res);//3
  </script>
  <script>
    function getMax(a, b) {
      if (a > b) {
        return a;
      } else {
        return b;
      }
    }
    var res = getMax(89, 65);
    console.log(res);
  </script>

利用函数求任意数组中的最大值

 <script>
    var arr1 = [5, 2, 99, 109, 67, 77];
    function getMax(arr) {
      max = arr[0];
      for (var i = 0; i < arr.length; i++) {
        if (arr[i] > max) {
          max = arr[i];
        }
      }
      return max;
    }
    console.log(getMax(arr1));
  </script>

return终止函数,return后面的语句不再执行

  <script>
    var arr1 = [5, 2, 99, 109, 67, 77];
    function getMax(arr) {
      var max = arr[0];
      for (var i = 0; i < arr.length; i++) {
        if (arr[i] > max) {
          max = arr[i];
        }
      }
      return max;
      alert("这句话在return后面,不再被执行")
    }
    console.log(getMax(arr1));
  </script>

return每次只能返回一个值,return后面跟多个值时,只返回最后一个值

  <script>
    function getNum(a, b, c) {
      return a, b, c;//只有c会被输出
    }
    console.log(getNum(8, 9, 23));//23
  </script>

想同时输出多个结果,就用数组

<script>
    function getRes(a, b) {
      var sum = a + b;
      var did = a / b;
      var mul = a * b;
      var min = a - b;
      return [sum, did, mul, min];

    }
    console.log(getRes(7, 3))
  </script>

函数有return,则返回return后的值,没有return,就返回undefined

  <script>
    function getRes(a, b) {
      var sum = a + b;
      var did = a / b;
      var mul = a * b;
      var min = a - b;
    }
    console.log(getRes(7, 3))//undefined
  </script>

10.6 arguments的使用

当不确定有多少个参数传递的时候,可以用arguments来获取。在JS中,arguments实际上是当前函数的一个内置对象,所有的函数都内置了一个arguments对象,arguments对象中存储了传递的所有实参,只有函数才有

arguments以伪数组的形式展示,因此可以进行遍历,具有以下特点:

【a】具有length属性

【b】按索引方式储存数据

【c】不具有数组的push,pop方法

 <script>
    function fn() {
      console.log(arguments);//Arguments(3) [1, 2, 3, callee: ƒ, Symbol(Symbol.iterator): ƒ]
      console.log(arguments.length);//3
      console.log(arguments[0]);//1
      console.log(arguments[1]);//2
      console.log(arguments[2]);//3
      for (var i = 0; i < arguments.length; i++) {
        console.log(arguments[i]);
      }
    }
    fn(1, 2, 3)

  </script>

利用arguments求任意数量的最大值

  <script>
    function getMax() {
      var max = arguments[0];
      for (var i = 1; i < arguments.length; i++) {
        if (arguments[i] > max) {
          max = arguments[i];
        }
      }
      return max;
    }
    console.log(getMax(1, 2, 3, 5, 8876, 342));//8876

  </script>

利用函数反转数组

  <script>
    arr1 = [23, 67, 1, 34, 78];
    function reverseArr(arr) {
      arr2 = [];
      for (var i = 0; i < arr.length; i++) {
        arr2[arr2.length] = arr1[arr1.length - i - 1];
      }
      return arr2
    }
    console.log(reverseArr(arr1))
  </script>

利用函数进行冒泡排序

<script>
    var arr1 = [90, 87, 99, 54, 78];
    function maoPao(arr) {
      for (var i = 0; i < arr.length-i; i++) {
        for (var j = 0; j < arr.length - i - 1; j++) {
          if (arr[j] > arr[j + 1]) {
            var temp = arr[j];
            arr[j] = arr[j + 1];
            arr[j + 1] = temp;
          }
        }
      }
      return arr;
    }
    console.log(maoPao(arr1))
  </script>

判断闰年

<script>
    function judgeYear(year) {
      var flag = false;
      if (year % 4 == 0 && year % 100 !== 0 || year % 400 == 0) {
        // return year + "是闰年"
        flag = true;
      }
      return flag;
    }
    console.log(judgeYear(2018));
  </script>

10.7 函数相互调用

  <script>
    function fn1() {
      console.log(11);
      fn2();
    }
    fn1();//11   22
    function fn2() {
      console.log(22);
    }
  </script>
  <script>
    function fn1() {
      console.log(111);
      fn2();
      console.log('fn1');
    }
    function fn2() {
      console.log(222);
      console.log('fn2');
    }
    fn1();//111,222,fn2,fn1
  </script>

判断是否是闰年

  <script>

    function isRunYear(year) {
      flag = false;
      if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
        flag = true;
      }
      return flag;
    }
    function getDays() {
      var year = Number(prompt("请输入年份"));
      if (isRunYear(year)) {
        return 29;
      } else {
        return 28;
      }
    }
    console.log(getDays())
  </script>

11.函数的两种声明方式

(1)命名函数

function fn(){

}

(2)函数表达式(匿名函数)

var 变量名=function(){}

var fun=function(){

console.log(我是函数表达式)
}
//调用方法
fun();
fun('aaa')

fun是变量名,不是函数名,匿名函数也可以传递参数

12.作用域

定义:代码名字(变量)在某个范围内有效果

js的作用域(es6版本之前):全局作用域,局部作用域,目的提高程序的可靠性,减少

命名冲突

(1)全局作用域,整个script标签或者一个单独的xx.js文件

<script>
//全局作用域
<script>

(2)局部作用域(函数作用域):在函数内部的就是局部作用域,这个代码的名字只在函数内部起作用,函数的形参也是局部变量

<script>
//全局作用域
function fn(){
//局部作用域
}

<script>

(3)块级作用域:在{}中的作用域

<script>
for{//块级作用域}
if{///块级作用域}
<script>

注意:ES6版本之后才有块级作用域

 <script>
    if (3 < 5) {
      var num = 9;
      console.log('块级作用域的结果' + num);
    }
    console.log(num);//外面不能调用num
  </script>

全局变量:在全局作用域下的变量,在全局下都可以使用,在函数内部没有声明直接赋值的变量也是全局变量

局部变量:在局部作用域中的变量,只能在函数内部使用,形参也是局部变量

  <script>
    var a = 9;//全局变量
    function getSum() {
      var b = 12;//局部变量
      return a + b;
    }
    console.log(getSum()) //21
    console.log(a);//9;
    // console.log(b);//报错,b是局部变量,不能在函数外部使用
    function getDid() {
      c = 30;//全局变量
      var d = 99;//局部变量
      return a - c;
    }
    console.log(getDid());//-21
    console.log(c);//30  //c在函数内部直接使用,是全局变量
    // console.log(d);//报错,d是局部变量,函数外不能使用

    function getMin(e, f) {
      console.log(e);
      console.log(f);
    }
    getMin(8, 9)//8,9
    //e,f是形参,是局部变量,在函数内部才能生效
    console.log(e);
    console.log(f);
  </script>

全局变量和局部变量的区别:

(1)全局变量只有浏览器关闭的时候才会被销毁,比较占内存

(2)局部变量当程序执行完毕时就会销毁,省内存

作用域链:根据在内部函数可以访问外部函数变量的机制就近原则,用链式查找决定哪些数据能被内部函数访问,就称为作用域链

  <script>
    var num = 9;
    var num2 = 10;
    function fn1() {
      num = 9;
      function fn2() {
        console.log(num);
        console.log(num2)
      }
      fn2()
    }
    fn1();//9 10 
    // fn2内没有num,就去fn1找,在fn1中找到了,输出num=9;fn2没有num2,
//在fn1中也没找到,就输出全局作用域的num2
  </script>
 <script>
    function fn1() {
      var num = 123;
      function fn2() {
        console.log(num);
      }
      fn2();
    }
    var num = 456;
    fn1();//123
  </script>
 <script>
    var a = 1;
    function fn1() {
      var a = 2;
      var b = '22';
      fn2();
      function fn2() {
        var a = 3;
        fn3();
        function fn3() {
          var a = 4;
          console.log(a);//4
          console.log(b);//'22'
        }
      }
    }
    fn1()
  </script>

解析:从console.log(a)出发,逐层向外寻找,遇到的第一个为a=4,b='22'

13. 预解析

13.1 Javascript代码的执行步骤

(1)预解析

定义:js引擎会把js里面所有的var和function提升到当前作用域的前面

(2)代码执行

按照代码书写顺序,从前到后依次解析

13.2 预解析分类

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

把所有的变量声明提升到当前作用域的最前面,只提升变量声明,不提升赋值

<script>
    console.log(num)//报错,没有声明num变量
  </script>
  <script>
    console.log(a);//undefined   
    //由于预解析,a被提升到当前作用域的最前面,对代码而言,它已经声明了a,但是没有赋值
    //故输出undefined
    a = 90;
  </script>
相当于执行
var a
console.log(a)
 <script>
    fun();
    var fun = function () {
      console.log(90);//报错
    }
    //因为fun前面有var,被当作变量处理,提升到当前作用域的最前面,此时被声明为变量,而不是函数
    //所以调用时报错
  </script>

相当于执行
var fun
fun()
fun=function(){
console.log(90)}

因此,对于匿名函数而言,函数调用必须放在函数声明之后

(2)函数预解析(函数提升)

把所有的函数声明提升到当前作用域的最前面,不调用函数

 <script>
    fn();//78
    function fn() {
      console.log(78);
    }//预解析时提升到最前面
    //由于预解析的存在,函数声明fn被提升到当前作用域的最前面,因此该程序可以正常运行
  </script>

相当于执行
 function fn() {
      console.log(78);
    }

fn()

预解析案例

<script>
    var num = 10;
    fun();
    function fun() {
      console.log(num);
      var num = 20;
    }
    //最终输出undefined
<script>


    //分析
    //提升第一步 变量+函数提升,源代码变成

    var num;//变量提升,只提升声明,不提升赋值,提升到当前作用域的最前面
    function fun() {//函数提升
      console.log(num);
      var num = 20;
    }
    //变量赋值
    num = 10;
    //函数调用
    fun();


    //提升第二步 函数内的变量提升
    var num;
    function fun() {
      var num;//变量提升,只提升声明,不提升赋值
      console.log(num);
      num = 20;
    }
    num = 10;
    fun()
//此时,从console.log(num)出发,已经执行的离他最近的就是函数fun内部的num,但是,num只是被声明,而没有赋值,
//所以输出undefined
 <script>
    var num = 10;
    function fn() {
      console.log(num);//输出undefined
      var num = 20;
      console.log(num);//输出20

    }
    fn()

  </script>

进行变量提升和函数提升后,相当于执行,以下按照顺序逐行执行
  var num;
    function fn() {
      var num;
      console.log(num);
//从这句出发,离他最近的是函数内部的num,未被赋值,输出undefined
    num = 20;
      console.log(num);
    //从这句出发,离他最近的是num=20,故输出20
    };
    num = 10;
    fn();

     
 <script>
    var a = 18;
    f1();
    function f1() {
      var b = 9;
      console.log(a);//undefined
      console.log(b);//9
      var a = '123';
    }

  </script>

//进行变量解析,只提升声明,不提升赋值,进行函数提升明知提升函数声明,不执行函数
//都提升到当前作用域的最前面,相当于执行
    var a;
    function f1() {
      var b;
      var a;
      b = 9;
      console.log(a);
//从这句出发,距离最近的是函数内声明但未赋值的a,故输出undefined
      console.log(b);
//从这句出发,距离最近的是函数内声明并赋值的b=9
      a = '123';
    }
    a = 18;
    f1();

 经典案例(面试常考)

  <script>
    fn1();
    console.log(c);
    console.log(b);
    console.log(a);
    function fn1() {
      var a = b = c = 9;
//相当于 var a=9; b=9; c=9;其中,b,c是全局变量,因为在函数内部没有声明而直接赋值
      console.log(a);
      console.log(b);
      console.log(c);
    }

  </script>

//相当于执行
    function fn1() {
      var a;
      a = 9;
      b = 9;
      c = 9;
      console.log(a);//9
      console.log(b);//9
      console.log(c);//9
    }
    fn1();
// b,c是全局变量,外部可调用,
    console.log(c);//9
    console.log(b);//9
//a是全局变量,外部不可调用,
    console.log(a);//报错

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值