阅读JavaScript文档-闭包


一、闭包的作用

  • JavaScript通过函数嵌套,使得内部函数可以访问定义在外部函数中的变量和函数,以及外部函数能够访问到的所有变量和函数
    但是外部函数无法直接访问定义在内部函数里的变量和函数,这样给内部函数的变量提供了安全性。
  • 由于内部函数可以访问外部函数定义的变量和函数,所以在内部函数生存周期大于外部函数时,会延长外部函数中定义的函数和变量的生命周期(即让一些变量始终保持在内存中,不会在外部函数调用完成之后就被清除)。

二、闭包的用法

1.基本的闭包(嵌套函数形成闭包)

  • 代码示例
        function outerfunc(x){
            var y=10
            function innerfunc(z){
                return x*y*z
            }
            return innerfunc
        }
    
  • 运行结果
    闭包1.png

2.嵌套函数

  • 说明
    一个函数里面嵌套另一个函数,内部函数的对于外部函数来说时私有的(内部函数定义的变量和函数外部函数是不可见的),但是外部函数的参数和变量内部函数都是可以访问的。一个闭包是一个可以拥有独立的环境和变量的表达式(通常为函数)

    闭包5

  • 代码示例

        function addSquares(a, b) {
            function square(x) {
              return x * x;
            }
            return square(a) + square(b);
        }
        a = addSquares(2, 3); // returns 13
        b = addSquares(3, 4); // returns 25
        c = addSquares(4, 5); // returns 41
    

    内部函数square形成闭包,可以调用外部函数并给外部函数和内部函数指定参数

3.链式作用域

  • 当多重嵌套时,内部函数会一层一层的继承外部函数的作用域
  • 代码示例
        function A(x) {
            return function B(y) {//继承x
              return function C(z) {//继承x,y
                console.log(x + y + z);
              }
            }
        }
        A(1)(2)(3); // 6
    

4.复杂的闭包示例

  • 在下面这种情形中,返回了一个包含可以操作外部函数的内部变量方法的对象。
  • 代码示例
        var createPet = function(name) {
            var sex;
    
            return {
                setName: function(newName) {
                    name = newName;
                },
                getName: function() {
                    return name;
                },
                getSex: function() {
                    return sex;
                },
                setSex: function(newSex) {
                    if(typeof newSex == "string"
                        && (newSex.toLowerCase() == "male" || newSex.toLowerCase() == "female")) {
                        sex = newSex;
                    }
                }
            }
        }
          
        var pet = createPet("Vivie");
        pet.getName();                  // Vivie
        pet.setName("Oliver");
        pet.setSex("male");
        pet.getSex();                   // male
        pet.getName();                  // Oliver
    

三、使用闭包可能会出现的问题

1.命名冲突

  • 未发生命名冲突的情况

    • 代码示例
          function outerfunc(){
              var x=10
              function innerfunc(){
                  return x*x;
              }
              return innerfunc
          }
      
    • 运行结果 闭包2
  • 发生命名冲突的情况

    • 代码示例
          function outerfunc(){
              var x=10
              function innerfunc(x){
                  return x*x;
              }
              return innerfunc
          }
      
    • 运行结果
      闭包3
  • 对比两者代码和结果可知

    • 当内部函数的参数和外部函数属性命名相同时,外部函数的属性将不会传递到内部函数内部
    • 在后面这种方式时,需要给内部函数指定参数,方可正常调用
      闭包4

2.内存消耗

  • 闭包会使函数的变量在内存中保存下来,如果滥用闭包会消耗大量内存,甚至还会产生大量的无效内存,产生网页性能问题。

参考

官方文档
1.JavaScript函数

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值