JS函数的应用 --- 初步总结(待完善)

一、立即执行函数 — IIFE

  • 立即执行函数的集中表现形式:

  • 立即执行函数的特点:

二、JS 全局污染

为什么会造成全局污染?
  • JS 没有块级作用域,在函数外定义的变量,均为全局变量;

  • 全局变量过多会削弱程序的灵活性,增大了模块之间的耦合度,多人协作开发会导致变量冲突,造成环境污染。

    • 耦合度:即模块之间的依赖关系:控制关系、调用关系、数据传递关系;
    • 划分模块准则:高内聚低耦合
如何解决全局污染?
1. 命名空间
2. 立即执行函数(里面创建的变量,为局部变量)
(function(){})()
(function(){}())
!function(){}()
var fn = function(){} ()

三、闭包

1. 闭包的概念
  • 广义闭包:函数内部声明变量,函数外部无法访问到,模拟块级作用域,即生成闭包

    • JS 中所有函数,都能形成一个闭包
  • 狭义闭包:闭包模型(一个函数,作为另一个函数的返回值)

  • 闭包实际上由两部分组成:

    • 函数体:函数的代码
    • 函数所处的环境:作用域链
  • 综上:把函数体 及 函数所处的环境,成为闭包

2. 主线:函数 不管在哪个环境下调用,都要回到创建函数的环境下执行
3. 闭包作用:
  • 解决全局污染

  • 对函数内的变量,起保护作用;除了返回函数外,没有任何办法可以访问到函数内的变量

4. 经典闭包模型
  • 可简单理解为,一个函数作为另一个函数的返回值;这样就有了内层函数,和外层函数;

  • 外层函数中:定义变量(对变量起保护作用)

  • 返回值返回的 内层函数:定义操作变量的方法

  • 闭包模型如下:

<script>
    var fn = function() {
        var num = 10;

        return {
            f1: function() {}
            f2: function() {}
        }
    };

    var temp = fn();

    // 调用 f1 、f2 方法
    temp.f1();
    temp.f2();
</script>
4. 闭包弊端(内存泄露)—> 解决:内层函数 = null
  • 闭包中外层函数定义的变量一直存在,不会被自动释放掉;

  • 因为内层函数一直引用着 外层函数中定义的变量;并且内层函数每一次操作变量,都是在外层函数中变量基础上进行操作的

  • 手动释放内存占用内层函数 = null

四、沙箱(闭包的一种体现形式)

1. 沙箱模式
  • 函数自调用

  • 给window注册属性 或 return 变量

  • 经典沙箱模式如下:

<script>
(function(window) {
    // 定义变量,及一些列js逻辑
    var main = '';

    window.main = main;  或  return main;
})(window)
</script>
  • jQuery中运用沙箱模式,如下:
(function() {

    window.jQuery = window.$ = jQuery;
    return jQuery;
})();
2. 沙箱的作用:
  • 变量隔离,保护变量(沙箱内定义的变量,沙箱外不能访问到)

  • 避免全局污染

3. IIFE 立即执行函数
(function(){})()
(function(){}())
!function(){}()
var fn = function(){} ()

五、函数 递归

1. 简单理解递归:函数自己 —> 调用自己
2. 何时用递归:函数需要多次调用自己,自己嵌套自己
3. 如何书写 递归函数(3点)?
    1. 划归思想:找出规律,总结前者 、 后者之间的关系
    1. 临界条件:找出临界值,停止递归
    1. retrun 自己函数的调用
4. 递归相关算法实现:
  • 递归实现兔子数列(菲波那切数列)
<script>
    function fn3(m) {
        if (m === 1 || m === 2) {
            return 1;
        }

        return fn3(m-1) + fn3(m-2);
    }

    console.log(fn3(20));
</script>
  • 菲波那切数列 优化【缓存】
<script>
    var cache = {};

    function fn4(m) {
        if (cache[m]) {
            return cache[m];
        }

        if (m === 1 || m === 2) {
            cache[m] = 1;
            return 1;
        } else {
            return cache[m] = fn4(m-1) + fn4(m-2);
        }
    }

    console.log(fn4(200));
</script>
  • 递归:阶乘
<script>
    function fn2(m) {
        if (m <= 1) {
            return 1;
        }

        return fn2(m-1) * m;
    }

    console.log(fn2(3));
</script>
  • 递归:次方
<script> 
    function fn1(m, n) {
        if (n === 0) {
            return 1;
        }

        return fn1(m, n -1) * m;
    }

    console.log(fn1(2,4));
</script>
5. 严格模式下,递归 —> 健壮代码
  • 非严格模式下,简易递归
<script>
    var fn = function (m) {
        if (m <= 1) {
            return 1;
        }

        return fn(m-1) * m;
    }

    var fn1 = fn;
    fn = null;

    console.log(fn1(3));  // 报错
</script>
  • 非严格模式下,健壮递归

    • arguments.callee 指向一个正在执行的函数的指针
<script>
    var fn = function (m) {
        if (m <= 1) {
            return 1;
        }

        return arguments.callee(m-1) * m;
    }

    var fn1 = fn;
    fn = null;

    console.log(fn1(3));  // 6
</script>
  • 严格模式下,不允许用 arguments.callee, 健壮代码如下:
<script>
    var fn1 = function fn(m) {
        if (m <= 1) {
            return 1;
        }

        return fn(m-1) * m;
    }

    var fn2 = fn1;
    fn1 = null;

    console.log(fn2(3));
</script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值