前端攻城狮---js之语法基础(2)

循环

分支结构(选择结构)
  • if

if结构

           if(条件) {
               条件成立时执行的语句
           } else {
               条件不成立时执行的语句
           }

else必须和if搭配,但是可以省略即

              if() {
              }

if还可以使用多种判断条件

            if() {
            } else if() {
            } else if() {
            }  ...
            else {
            } 

if里面还可以嵌套着if

            if() {
if() {
              }
            }

  • switch
          switch(){
          case  :
          break;
          case  :
                  break;
          ...
          default  :
                  break;
          }
循环结构
  • for循环

        for(var i=1; i<=50; i++) {
         console.log("第"+i+"次");
     }

表达式1 var i = 1  表达式2  i<=50  循环条件  表达式3 i++  三个表达式用分号隔开  循环体------大括号的语句(需要重复执行的语句)

执行流程: S1 先执行表达式1 

               S2 再执行表达式2,表达式2为真,继续S3
               假如表达式2为假,循环到此结束
               S3 执行循环体

               S4 S3完成后,执行表达式3 继续回到S2

  • 循环嵌套

      for(var i = 0;i<50;i++){
      for(var j = 0;j<50;j++){
     
      }
      }

  • break与continue

break用于switch或任何循环中,表示跳出相应的结构
continue只用于循环,结束本次循环继续下一次循环

  • while循环

while(条件) {
           循环体
        }

循环体可能一次都不执行,因为条件可能一开始就不满足。

  • do-while循环

         do {
             循环体
         }while(条件);

循环体一定执行至少一遍

来个小demo吧

游戏开始,系统随机生成一个地雷数 1~100 比如68,系统提示请输入一个数字 范围1~100,用户输入45,系统提示 恭喜没有猜到地雷 下一个人接着猜  范围45~100 下一个输入78,系统提示恭喜没有猜到地雷 下一个人接着猜 范围45~78
假如输入的数字 比地雷数大 上限改成用户输入的数
假如输入的数字 比地雷数小 下限改成用户输入的数

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Document</title>
</head>
<body>
	<script type="text/javascript">
		var min_num = 0;
		var max_num = 100;
		var input_num = parseInt(prompt("请输入"+min_num+"~"+max_num+"的数字"));
		var random_num = parseInt(Math.random()*100+1);
		console.log(random_num);
		while(input_num!=random_num){
			if(input_num>random_num){
				if (input_num>max_num) {
					input_num = parseInt(prompt("请输入"+min_num+"~"+max_num+"的数字"));
					continue;
				}
				max_num = input_num;
				input_num = parseInt(prompt("请输入"+min_num+"~"+max_num+"的数字"));
			}else if (input_num<random_num) {
				if (input_num<min_num) {
					input_num = parseInt(prompt("请输入"+min_num+"~"+max_num+"的数字"));
					continue;
				}
				min_num = input_num;
				input_num = parseInt(prompt("请输入"+min_num+"~"+max_num+"的数字"));
			}
		}
		alert("恭喜你答对了,答案是"+random_num);
	</script>
</body>
</html>

函数

函数定义和调用

         function  函数名() {
              // 函数体
         }

        函数名(); //调用函数

以上就是函数定义和函数的调用,切记函数的调用要加括号,不加括号只能表达函数这个对象。

函数意义

当大量程序相同时候,可以封装成一个function,这样封装一次,多次调用

函数的参数

         function  函数名(参数1,参数2,参数3.....) {
              // 函数体
         }

函数的参数就是写在括号里面,可以是一个,两个,三个甚至是多个

   function add(a,b) {
                   console.log(a+b);
   }
   add(10,10);
   add(40,50);

函数的返回值

    function sum(a,b) {
    // 函数体------具体功能的实现
                var c = a + b;
                //console.log(c); 
                // 结果返回出去
                return c; // 返回c的值

                c++;//不执行

            }

需要通过return去返回一个值,一旦有return返回值了,那么retuen后面的代码就都不执行。

函数表达式

函数表达式也是定义函数的一种方式 比如
      var sum = function(num1,num2) {
    return num1 + num2;
    }

等号右边的可以是一个没有名字的函数(匿名函数),也可以是一个有函数名的函数

函数声明提升(预解析)

有参数声明提示,肯定也有函数声明提升。

情况1:

alert(a()); 

function a(){alert(1)};

则会出现弹框内容是1,因为js会将所有函数声明进行提升,即使函数声明在函数调用之后,也不会报错,也能正常的解析函数。若此时alert(a),弹出的不是结果而是整个函数的内容了。所有调用函数要加括号。

情况2:

alert(a());                      
var a = function(){
                alert(1);   
};

会报错提示找不到函数a,因为函数表达式不会被提升,

情况3:    

        fun();
      var fun;
      function fun() {
           alert(1);
      }
      fun = function() {
           alert(2);
      }                

此时弹框的内容是1,不是2,函数优先 遇到同名标识符 预解析阶段一定把这个标识符给函数。

若是下面顺序

        var fun;
      fun = function() {
      alert(2);
      }  
fun(); // 显示2
      function fun() {
      alert(1);
      }

若在调用方法前,已经声明了函数,则就不会去调用预解析中同名的方法。

函数也是引用类型

什么是引用类型呢?引用类型是是一种将数据和功能组织在一起的数据类型。我们可以给该数据类型添加属性,方法等。

   var fun = function() {
       alert("ok");
   }
   //alert(typeof fun);// function也是一种类型 属于引用类型的一种
   var fun2 = fun;
   fun2.aa = 10; //
   console.log(fun.aa);//10
   fun2.aa++;
   fun2.aa++;
   console.log(fun.aa); // 12
   fun2();

我们来看看,我们将fun函数对象赋予了fun2,并且给fun2对象添加了一个aa属性并且赋值于10,之后对aa进行递增,最后显示的值是12,我们还能去调用方法。这些操作很符合应用类型的定义,是一个将数据和功能组织在一起的数据类型。

作用域

函数能够封闭住定义域

         function fun() {
    var num = 10;
    console.log("我是函数里的语句,我可以认识num,它的值为"+num);
  }
  fun();
  console.log(num);//报错

那么编译时就会报错,因为num是个变量被函数封闭住了,可以说num变成了局部变量,在函数以外是访问不到的,所以在log的时候报错找不到num的错误

总结一下作用于

  1. 在函数内部通过var定义的变量叫局部变量,使用有效范围在函数里面
  2. js变量作用域非常简单,没有块级作用域,只有函数可以管理住作用域
  3. 函数外定义的变量 是全局变量,都认识
作用域链

什么叫作用域链?我更理解为是一个动词,它表示的是在一个父函数中嵌套这子函数,子函数在使用参数时,会逐级往上找,这么个动作称之为作用域链。

      var a = 1;
      var b = 2;
      function outer() {
          var a = 3;
          function inner() {
             var b = 4;
             conosle.log(a); (1)
             conosle.log(b);(2)
          }
          inner();
          conosle.log(a); (3)
          conosle.log(b); (4)
      }
      outer();
      conosle.log(a); (5)
      conosle.log(b); (6)

我们来分析一下这6处的输出的值。

(1)输出3,在inner函数中没有a这个参数,所以就往上找,找到父亲outer中的3并显示出来

(2)输出4,因为在inner函数中就有b这个参数,故显示4

(3)输出3,直接找到了自己(outer)的函数体中的参数a,显示3

(4)输出2,因为在自己(outer)的函数体中没有b这个参数,故只能往全局变量中找,显示2

(5)输出1,该log在函数体外,故在全局变量中找,显示1

(6)输出2,同5,在全局变量中找,显示2

隐式全局变量

隐式全局变量,就是不写var的变量自动变成全局变量

    function fn() {
    b = 12; // 没有通过var去定义b 
    }
    fn();
    console.log(b); // 12

在函数中没有用var去定义b,那么b就是全局变量,显示12还不会报错。

函数参数,默认定义为局部变量

    function fun(a,b,c) {
        // 相当于 var a,b,c
    }

那么a,b,c就是该函数的局部变量,只限在函数体里使用。

函数定义也有作用域

这句话怎么理解呢?就是父函数内定义了个子函数,在父函数外去调用子函数,那么调用时一定报错,因为子函数此时可以理解为一个局部变量,外部当然访问不到,也获取不到。若一定要访问,可通过return子函数。

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Document</title>
</head>
<body>
	<script type="text/javascript">
	    // 返回a的平方与b的平方和 
	    function pingfanghe(a,b) {
	    	return pingfang(a)+pingfang(b);
	    	// 返回m的平方
	    	function pingfang(m) {
	    		return Math.pow(m,2);
	    	}
	    }
	    var res = pingfanghe(3,4);
	    var res2 = pingfang(6); // 报错 因为离开外面函数没有作用域
	</script>
</body>
</html>

我们来分析一下,var res = pingfanghe(3,4);这含代码是不会报错的,同时也达到目的去调用pingfang的函数,因为父函数通过return的形式去返回一个pingfang函数。然而var res = pingfanghe(3,4);直接调用了内部的函数,此时被调函数的作用域只在pingfanghe内,故会报错。

闭包

其实上述问题就是一个闭包。那么什么是闭包。先上代码

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Document</title>
</head>
<body>
	
	<script type="text/javascript">
	    function outer() {
	    	var num = 666;
	    	function inner() {
	    		console.log(num);
	    	}
	    	return inner; // outer函数返回 inner的引用
	    }
	    var inner = outer();
	    inner();// 666 
	</script>
</body>
</html>

就因为函数也是有作用域的,所以我们想要获取到内部函数,需要通过外部函数去retuen获得。因为闭包我们才需要这么做。

先来个简单的理解闭包:一个函数可以把它自己内部的语句,和自己声明时所处的作用域一起封装成了一个密闭的环境,我们称为"闭包"。因为函数的闭包,inner和num被封装在outer的密闭的环境里,因为实在密闭的环境里,所以在outer函数的外部我们是不能直接访问到inne函数。

再来个稍微复杂点的理解闭包:Javascript允许使用内部函数---即函数定义和函数表达式位于另一个函数的函数体内。而且,这些内部函数可以访问它们所在的外部函数中声明的所有局部变量、参数和声明的其他内部函数。当其中一个这样的内部函数在包含它们的外部函数之外被调用时,就会形成闭包。

每个函数都是闭包,每个函数都天生可以记住定义时所处的作用域。怎么理解看看下面的demo

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Document</title>
</head>
<body>
	<script type="text/javascript">
	    var inner;// 全局变量
	    function outer() {
	    	var num1 = 260;
	    	var num2 = 360;
	    	// inner变成一个函数
	    	inner = function() {
	    		 alert(num1);
	    		 alert(num2);
	    	}
	    }
	    outer();
	    var num1 = 300;
	    var num2 = 100;
	    inner(); // 260 360
	</script>
</body>
</html>
我们来看看上面的那个例子,最后的弹框内容是260 360,虽然函数体外定义了同名的num1 num2,但是由于闭包,inner记住了声明时所处的定义域,所有弹出的内容是260 360.

每次重新声明函数,闭包都是新的

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Document</title>
</head>
<body>
	
	<script type="text/javascript">
	    function outer() {
	    	var count = 0;
	    	function  inner() {
	    		count++;
	    		console.log(count);
	    	}
	    	return inner;
	    }
	    var inn1 = outer();
	    var inn2 = outer();
	    inn1();// 1
	    inn1();// 2
	    inn1();// 3
	    inn2();// 1
	    inn2();// 2
	    inn2();// 3
	</script>
</body>
</html>

我们可以看到inn1 和 inn2第一次调用都是1,也就是说每一次重新声明函数都是新的,并没有接着上一个函数内参数值继续做自增。


js之语法基础循环与函数部分已经讲完,接下来会来讲js之语法基础的数组和字符串相关知识点,如有表达错的请谅解,并请提出指出,且修改错误,望能共同进步。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值