函数-02

递归

 function auto(){//无限执行,自己调用自己
        auto();
      }
  auto();

在这里插入图片描述
会报错(调用栈溢出重复执行导致内存不够

在函数内部 重复调用函数自身 这个情况叫做递归

1.求1-100之内的所有偶数和

2+4+6+8+10+...100//1-100之内的偶数
100+98+96+...+4+2
function sum(n){
           if(n==0){//递归出口
               return 0;
           }
           return n+sum(n-2);//定义了一个条件
      }
      var result = sum(100);
      console.log(result);
 n=100
    sum(100)
       100+sum(98)
          98+sum(96)
            96+sum(94)
             94+sum(92)
             ...
             ...
               4+sum(2)
                  2+sum(0)

           n=4
               4+sum(2)  4+2
           n=2
               2+sum(0)  2+0
           n=0
               0

使用递归做某事时:首先是函数内部必须是使用自己调用自己的函数但是一定要找到递归出口如果找不找出口就会一直执行下去

2、 求n的阶乘

求n的阶乘
        5! = 5*4*3*2*1
           = 5*4!
               4*3!
                  3*2!
                    2*1!
                       1

        7! = 7*6*5*4*3*2*1
        n! = n*(n-1)*(n-2)*(n-3)*...2*1

        n=5
           fn(5)
           5*fn(4)
               4*fn(3)
                   3*fn(2)
                     2*fn(1)
    function fn(n){
        if(n==1){//递归出口
            return 1;
        }
        return n*fn(n-1)  //定义了一个条件
        当n=5时 这个return 必须等到5*fn(4)的结果算出来之后 才能结束函数
    }
    
    var result = fn(5);
    console.log(result);

3、求1-100之内所有能被3并且被5整除的数字之和

/*
    *
    *   求1-100之内所有能被3并且被5整除的数字之和
    *
    *
    *   fn(100)
    *   fn(99)
    *   fn(98)
    *   ...
    *   fn(90)
    *   90+fn(89)
    *       fn(88)
    *       fn(87)
    *       ...
    *       fn(75)
    *       75+fn(74)
    *           fn(73)
    *           ...
    *           fn(60)
    *           60+fn(59)
    *           ...
    *           fn(45)
    *              45+fn(44)
    *              ...
    *              fn(30)
    *              30+fn(29)
    *               ...
    *              fn(15)
    *               15+fn(14)
    *               ...
    *               fn(2)  0
    *               fn(1)  0
    *               fn(0)  0
    *
    *
    *
    *
    * */
  function fn(n){
        if(n==0){//递归出口
            return 0
        }
        if(n%3==0&&n%5==0){    //能够被3 和 5整除的数字
            return n+fn(n-1)//定义了一个条件
        }
        return fn(n-1)
    }
    var result = fn(100);
    console.log(result)

作用域

在JS中 变量有两个存放的区域

  1. 全局作用域
  2. 函数作用域

在函数作用域中可以使用全局变量
在全局作用域中不能够使用函数中的变量

var a = 1;//全局作用域中的变量
        function auto(){
            var a = 2;//函数作用域中的变量
            console.log(2);
        }
        auto();

全局作用域

全局变量会自动成为window对象的属性

window对象也可以叫做Global Object GO对象

打开浏览器 自动生成window对象

关闭浏览器 window对象就自动销毁了

console.log(window);

在这里插入图片描述
打开浏览器,浏览器会自动把全局变量储存在 window对象里也就是Global Object GO对象

var b = 'heaven';
console.log(window);

把变量b作为GO对象的属性名字,值heaven作为GO对象属性值把他存起来
在这里插入图片描述

一旦关掉浏览器window对象就不复存在

		function auto(){-->auto是全局作用域中的变量储存在GO对象里
            var a = 2;//函数作用域中的变量
            console.log(2);
        }
        auto();

在这里插入图片描述

 var heaven = function(){//函数表达式也可以在全局变量中
        console.log('heaven');
    }

在这里插入图片描述

无论是变量还是函数,他都被放在全局变量当中,只要你是身处在全局

   GO {
      b:'heaven',
      auto:function(){},
      heaven:function(){}
    }

全局的预编译三步:

  1. 创建GO对象 ==> Global Object(GO对象)
  2. 找到变量,把变量作为GO对象的属性名,值是undefined
  3. 在全局中找到函数声明,把函数名作为GO对象的属性名,值是函数体

预编译之后才能执行JS代码

等到关闭浏览器的时候 GO对象就会被销毁了

函数作用域
Js解释引擎执行js代码的步骤

语法分析

Js解释引擎会先扫描所有的js代码,查看代码有没有低级的语法错误,如果存在语法错误,则整个程序就不会执行,如果没有语法错误,则进入预编译阶段

报错信息:Uncaught SyntaxError:Invalid or unexpected token表示语法错误

函数的预编译四步(当时函数没有执行)

  1. 创建AO对象 ==> Activated Object(活动对象)【激活状态】
  2. 找到形参和变量,把形参和变量作为AO对象的属性名,值是undefined
  3. 实参把值赋给形参
  4. 函数中找到函数声明,把函数名作为AO对象的属性名值是函数体

预编译之后才能执行JS代码

等到函数执行完成后(return) AO对象就会被销毁了

 function auto(a){
            var b = 3; --->var b;--->b=3;
            console.log(a,b);
        }
        auto(2);
        /*
          1,AO{
              a:2,undefined -->3,a:2
              b:2,b -->3,b:3
          }预先编译的环节,然后就执行函数内部的代码了
          函数的预编译四步结束了
          不符合条件直接跳过预编译然后就执行js代码
        */

AO对象就像一个小型的仓库,他可以储存函数作用域中的变量,可以查找函数中的变量
在这里插入图片描述

 function outer(){
        /*
        * AO{
        *   b:3,
        *   inner:function(){}
        * }
        * */
        function inner(){
            /*
            *   AO{
            *       a:4
            *   }
            * */
            var a = 4;
            c = 5;  //一个变量  没有var关键词 直接赋值 则这个是全局的  叫做暗示全局变量
            console.log(a);     //4  inner的AO中找到变量a
            console.log(b);     //3  outer的AO中找到变量b
            console.log(c);     //5  GO中找到变量c

        }
        var b = 3;
        inner();
    }
    var a = 2;
    outer();

    console.log(outer);

    /*
    *   GO{
    *       a:2,
    *       outer:function(){},
    *       c:5
    *   }
    *
    * */

c = 5; 一个变量 没有var关键词 直接赋值 则这个是全局的 叫做暗示全局变量

GOAO都是相互独立的,如果没有相对应的变量会往父级去找,如果有就不会去父级找了

作用域有两个规则

  1. 规则是用来定义变量到底储存在哪里的
  2. 如何查询
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值