js闭包示例与函数声明的理解

var add =(function(){
  var counter = 0;
  return function(){
    return counter += 1
  }
})()
add()   //1
add()   //2
add()   //3

疑问:为什么每次执行add()之后结果是递增的而不是都是1呢?

上面的函数可以拆解为

function test() {
    var counter = 0;
    return function() {
        return counter += 1;
    };
}
var add = test();

即将test函数赋值给addaddtest函数的返回值,即return counter += 1

test()只在赋值的时候执行了一次,执行了三次add(),每一次都有counter+=1add()返回的counter其实是引用了函数外定义的counter

一、函数声明和函数表达式的区别

  • 函数声明不能加括号不会立即执行
  • 函数表达式可以加括号立即执行
  • 函数声明立即调用的方法:用“()”包起来形成函数表达式,加上括号立即使用
//函数声明
function f1(){
    //...
}()         //加括号会报错

//函数表达式
var functionName = function() {
   //...
}()        //加括号表示立即执行

//函数声明立即执行
(function f1(){
    //...
})()

所以在这个例子中,由于函数被包含在()括号内,并在最后加了一个()表示立即执行函数,所以在运行代码的时候add其实变成了add = function () {return counter += 1;}

二、闭包

理解:
保护私有变量的机制,在函数执行时形成私有的作用域,保护里面的私有变量不受外界的干扰。直观的说就是形成一个不销毁的栈环境。

特点:

  1. 闭包可以记住并访问词法作用域,即使得函数是在当前词法作用域外执行,就会形成闭包。闭包是指有权访问另一个函数作用域中的变量的函数
  2. 闭包有两种基本情况:闭包的返回值是一个函数,它其中使用了该闭包的局部变量;闭包内定义了内部函数,内部函数引用了闭包的局部变量
  3. 拥有更多长的生命周期

作用:

  1. 能在一个函数外访问函数中的局部变量
  2. 防止对全局作用域的污染

从闭包解释上面这段代码

  1. 执行add函数的时候并没有重新声明函数,立即执行该函数此时的返回值就一个闭包。每次调用add函数实际上都是在使用这个闭包
  2. 闭包可以记住词法作用域的标识符(即这段代码中的counter),所以再次调用函数的时候可以记住上次累加的counter的值
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值