美文网首页
JavaScript(第五天)—爱创课堂专业前端培训

JavaScript(第五天)—爱创课堂专业前端培训

作者: 爱创课堂 | 来源:发表于2019-10-14 17:33 被阅读0次

    一、递归函数

    函数内部调用函数本身;

    如果函数一直自己调用自己,那么就成了死循环。程序就会造成内存堆栈溢出,终止程序;

    所以,递归函数一定要给一个条件,来跳出函数。

    递归一般用来解决数学问题;

    一般是大于0的自然数的处理!!!

    如:求阶乘 5!=5*4*3*2*1

    // fn();// function fn() {//     fn();// }//Uncaught RangeError: Maximum call stack size exceeded//求阶乘 5!=5*4*3*2*1console.log(jieCheng(5));//累乘法// function jieCheng(num) {//     var result = 1;//     for (var i = 5; i > 0; i--) {//        result *= i;//     }//     return result;// }//递归函数法function jieCheng(n) {    if(n === 1){        return 1;    }    return n * jieCheng(n-1);}/** 函数调用,传参5* 返回:5 * jieCheng(5-1) = 5 * 4 * jieCheng(4-1) = 5 * 4 * 3 * jieCheng(3-1)*                         = 5 * 4 * 3 * 2 * jieCheng(2-1)*                         = 5 * 4 * 3 * 2 * 1*                         = 120* */

    1  

    求斐波那契数列 1,1,2,3,5,8,13,21,34,55……,求第N项是多少

    console.log(feiBo(5));console.log(feiBo(6));console.log(feiBo(7));console.log(feiBo(8));console.log(feiBo(9));console.log(feiBo(10));console.log(feiBo(11));function feiBo(n) {    if(n === 1 || n === 2){        return 1;    }    return feiBo(n-1)+feiBo(n-2);}/** feiBo(n) = feiBo(5) = feiBo(5-1) + feBo(5-2) = feiBo(4) + feiBo(3)*                     = (feiBo(4-1) + FeiBo(4-2)) + (feiBo(3-1) + feiBo(3-2))*                     = (feiBo(3) + feiBo(2)) + ( feiBo(2)+feiBo(1))*                     = feiBo(3) + 2 * feiBo(2) + feiBo(1)*                     = (feiBo(3-1) + feiBo(3-2)) +  2 * 1 + 1*                     = feiBo(2) + feiBo(1) + 2 + 1*                     = 1 + 1 + 2 + 1*                     = 5* */

    二、立即执行函数与匿名函数

    立即执行函数:也叫自执行函数,IIFE函数;程序运行,函数即可自动执行;由效果对函数体进行包裹,后面一对小括号执行函数。

    匿名函数:没有名字的函数

    2 (function(形参){

    //函数体

    3 })(实参);

    (function (a,b) {    console.log(a+b);})(10,20);

    注:一般自执行函数用于加载页面时,只执行一次的操作

    补充:函数体除了可以使用小括号进行包裹,还可以在函数体前面加 ~!  +  -

    (function (a,b) {    console.log(a+b);})(10,20);~function (a,b) {    console.log(a+b);}(10,20);!function (a,b) {    console.log(a+b);}(10,20);-function (a,b) {    console.log(a+b);}(10,20);+function (a,b) {    console.log(a+b);}(10,20);

    三、闭包函数

    概念:一个函数可以调用另外一个函数内部的变量

    提取关键字:

    两个函数

    局部作用域

    局部变量只能在变量当前作用域内被调用,作用域外部是没有办法调用到这个变量。

    那么想要访问一个函数内部的变量,就需要从这个函数内部声明一个子函数,那么这个子函数就可以任意的调用父函数中的变量了。反之,父函数却不能调用子函数中的变量。这就是js中存在的链式作用域的概念。

    var str = "Hello World!!";console.log(fn());//ƒ fn2() {console.log("num:",num);}console.log("num:",fn()());//num: 10function fn() {    var num = 10;    // console.log("num:",num);    function fn2() {        // console.log("num:",num);        return num;    }    return fn2;}// console.log("num:",num);// num is  not  defined

    但是,这种fn2形成的闭包函数,并不是我们所要说的。我们想要的是函数外部的函数可以调用这个函数内部的局部变量。

    思考?可不可以将内部的函数作为一个桥梁,来连接内外 ,作为一个传递数据的通道

    function fn() {    var num = 10;    return function () {        return num;    }}console.log("fn函数:",fn());console.log("fn内部匿名函数执行结果:",fn()());//现在想要在fn函数的外部调用fn内部的变量num,该怎么做???var test = fn();//test 和 内部的匿名函数一样,形成一个闭包;都叫做闭包函数console.log("test函数:",test);console.log("test函数执行结果:",test());

    闭包函数的特点:

    观察下面代码,内部匿名函数,每一次执行,都是一次全新的开始,会形成一个新的闭包;

    但是用外部变量test或test2来声明接收的fn内部匿名函数的赋值,test或test2函数会形成自己的闭包;

    由于fn内部匿名函数和变量是局部的,单独执行调用时生成,调用完毕结束;

    但是test或test2不同,它是一个全局变量(函数),全局就是页面生成时创建,关闭销毁;常驻内存了。

    以test为例,从内存角度来讲,与fn内部的匿名函数建立了一个引用关系,而这个匿名函数又和fn内部的变量num有引用关系;在js中,有一个垃圾回收机制,只有当对象之间不存在引用关系时,才会回收。所以,test去调用的num并没有被回收,而是常驻内存,所以在我们连续执行几次test之后,num依次递增。

    function fn() {    var num = 10;    return function () {        return num++;    }}

    // console.log("fn函数:",fn());// console.log("fn内部匿名函数执行结果:",fn()());//现在想要在fn函数的外部调用fn内部的变量num,该怎么做???var test = fn();var test2 = fn();// console.log("test函数:",test);// console.log("test函数执行结果:",test());console.group("fn内部的函数连续执行4次");console.log("fn内部的函数第1次执行",fn()());//10console.log("fn内部的函数第2次执行",fn()());//10console.log("fn内部的函数第3次执行",fn()());//10console.log("fn内部的函数第4次执行",fn()());//10console.log("fn内部的函数每一次执行都会形成一个新的闭包")console.groupEnd();console.group("test函数连续执行4次");console.log("test函数第1次执行:",test());//10console.log("test函数第2次执行:",test());//11console.log("test函数第3次执行:",test());//12console.log("test函数第4次执行:",test());//13console.groupEnd();console.log(test2());//10console.log(test2());//11

    闭包函数使用过多:可能会造成内存泄漏的问题,以及对全局变量造成污染。

    但是在很多高级程序开发过程中,也会经常用到闭包,闭包是一个重点也是一个难点。

    闭包的应用:

    在循环中的应用:定时器和事件函数

    求fn(3)(4)(5)(6),结果是 360

    // 求fn(3)(4)(5)(6),结果是 360console.log(fn(3)(4)(5)(6));function fn(num1) {    return function (num2) {        return function (num3) {            return function (num4) {                return num1 * num2 * num3 * num4;            }        }    }}

    1

    关注VX公众号“icketang” 免费领取华为荣耀商城项目实战视频教程

    相关文章

      网友评论

          本文标题:JavaScript(第五天)—爱创课堂专业前端培训

          本文链接:https://www.haomeiwen.com/subject/oajoectx.html