JavaScript闭包解决的问题

南笙酒味 提交于 2019-12-01 10:03:28

一、引入

我们假如想实现一个计数器的功能,我们可能会像下面这样写。

var count = 0;

function increase(){

return ++count ;

}

这样从功能角度上看是可以的,但是从设计角度看是不优雅的,很明显的一个问题就是向外暴露了内部成员,外部能够直接操作它,可能会导致计数错误。而且还会污染全局命名空间。

在像C/C++、这种语言中,我们可以用局部静态变量来实现。如下

unsigned int increase()

{

static unsigned int count = 0;

return ++count;

}

在JavaScript中,是没有静态变量这个概念的,像下面一样。

function add(){

static var count = 0;

return ++count;

}

这样使用会报错。

那么有没有一种可行的方式,能够像使用静态变量一样呢?答案就是闭包。

二、闭包

在Javascript中有嵌套函数这个概念,我们可以用嵌套函数来实现局部静态变量的功能。那么什么是嵌套函数?

1.嵌套函数

字面上意思,我们可以在函数中嵌套函数。如下所示

function host() {

var count = 0;

var increase = function () {

return ++count;

            };

console.log(increase());

console.log(increase());

console.log(increase());

        }

在控制台调用func()得到如下结果:

image

可以发现,count这个函数中的变量可以被它所在函数的下的嵌套函数中使用。那么这有什么用呢?我们可以这样想,如果我们可以在外部(函数func()的外部)调用increase()这个函数,那么我们是不是就可以认为count这个变量相当于一个静态局部变量,从而可以实现计数的功能呢?那么问题来了,怎么在外部使用func()函数内部的嵌套函数呢?答案是我们可以使用对象引用。让宿主函数(func())返回一个函数引用。我们编写如下代码测试:

function host(){

var count = 0;

var increase = function () {

return ++count;

            };

return increase;

}

var add = host();

console.log(add());

console.log(add());

console.log(add());

image

我们使用匿名函数简写

var add = function () {

var count = 0;

var increase = function () {

return ++count;

            };

return increase;

}

console.log(add());

console.log(add());

console.log(add());

image

可以发现返回了函数的引用,让我们在修改一下代码

var add = function () {

var count = 0;

var increase = function () {

return ++count;

            };

return increase;

}

console.log(add()());//注意多加了个括号

console.log(add()());

console.log(add()());

image

可以发现并没有实现我们想要的效果,原因出在哪里呢?

分析可以发现,每次我们调用add()的时候,返回的都是不同的increase实例,因此,我们需要返回同一个实例。我们可以这么做

var add = function () {

var count = 0;

var increase = function () {

return ++count;

            };

return increase;

}


add = add();

console.log(add());//注意去掉了括号

console.log(add());

console.log(add());

也可以这么做

var add = function () {

var count = 0;

var increase = function () {

return ++count;

            };

return increase;

}()


//add = add();

console.log(add());//注意去掉了括号

console.log(add());

console.log(add());


易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!