JavaScript之闭包【三】

369 阅读3分钟

以下你将了解到:

1、什么是闭包
2、为什么用闭包
3、闭包的使用场景以及注意事项

一、介绍闭包之前,我们先了解下--变量和作用域

1、在 JavaScript 中, 对象和函数同样也是变量

2、作用域:可访问变量的集合

  • 局部作用域:变量在函数内部定义【局部变量】,只能在函数内部访问
function initData(){
    var name = 'zjl';
    console.log('name==>'+name);//name==> zjl
}
console.log('out name==>'+name);//out name==> null
initData();

注:局部变量,在函数执行时被创建,执行结束自动销毁

  • 全局作用域:变量在函数外定义【全局变量】
var name = 'zjl';
function initData(){
    console.log('name==>'+name);//name==> zjl
}
console.log('out name==>'+name);//out name==> zjl
initData();

注:全局变量在页面关闭后销毁

function initData(){
    name = 'zjl';
    console.log('name==>'+name);//name==> zjl
}
var name='lisi';
console.log('out name==>'+name);//out name==> lisi
initData();

注1:上面代码,如果在函数initData内部定义变量,不加关键字var即为全局变量 当我们想通过函数外部访问函数内部局部变量,或一个函数访问另一个函数的内部局部变量时,该怎么做呢?这就需要想个办法间接的访问局部变量。闭包就派上了用场,现在我们通过一个例子看看,怎么实现一个闭包:

注2:作用域链是描述一种路径的术语,沿着该路径可以确定变量的值 .当执行name = 'zjl'时,因为没有使用var关键字,因此赋值操作会沿着作用域链到var ='lisi'; 并改变其值.

不用闭包时:out name==> null

function initData(){
    var name = 'zjl';
    console.log('name==>'+name);//name==> zjl
}
console.log('out name==>'+name);//out name==> null
initData();

用闭包:

var getName = (function initData(){
    var name = 'zjl';
    function getName(){ return name}
    return getName;
})()
console.log('out name==>'+getName());//out name==> zjl

上面的代码,就是一个典型的闭包实现,闭包可以理解为函数内部的函数,这个内部函数可以访问上级作用域变量. 闭包【内部函数】作为,外部函数访问内部变量的桥梁

二、为什么用闭包呢 其实上面也已经提到,闭包还有另一个用处,就是驻留内存.比如实现计数器的累加,就需要变量常驻内存进行累加.因全部变量常驻内存的,所以再使用闭包的时候也要慎重,局部变量有可能不能被及时的释放掉,有可能造成内存的泄漏.以上面的例子,来看下:

var getName = (function initData(){
    var name = 'zjl';
    function getName(){ return name}
    return getName;
})()
console.log('out name==>'+getName());//out name==> zjl

由于外函数,被赋值到一个全局的变量getName.由于全局变量常驻内存的,界面不关闭内存得不到释放,局部变量也不会被释放.如果内函数【闭包】循环调用很容易造成内存泄漏.这种情况,在全部函数调用完之后,把不需要的局部变量释放掉.

var name = "The Window";
var object = {
    name: "My Object",
    getNameFunc: function() {
        return function() {
            return this.name;
        };
    }
};
alert(object.getNameFunc()()); //The Window

function outerFun() {
    var a = 0;
    innerFun:function () {
        return function(){ a++;}
    },
    clear:function(){
        a=null;
    }
}
var obj = outerFun();
obj.innerFun(); //结果为1
obj.innerFun(); //结果为2
var obj2 = outerFun();
obj2.innerFun(); //结果为1
obj2.innerFun(); //结果为2

obj.clear();
obj2.clear();

JavaScript之内存泄漏【四】