js 闭包(面试题)

JavaScript025

js 闭包(面试题),第1张

1. 闭包的本质就是在一个函数内部创建另一个函数。

2

匿名函数作为fun的返回值被赋值给了f,

这时候相当于 f=function(){var n = 0 … },

并且匿名函数内部引用着fun里的变量num,所以变量num无法被销毁,

而变量n是每次被调用时新创建的,所以每次 f 执行完后它就把属于自己的变量连同自己一起销毁,

于是乎最后就剩下孤零零的num,于是这里就产生了内存消耗的问题

3. 定时器与闭包

最后总结一下闭包的好处与坏处

好处

①保护函数内的变量安全 ,实现封装,防止变量流入其他环境发生命名冲突

②在内存中维持一个变量,可以做缓存(但使用多了同时也是一项缺点,消耗内存)

③匿名自执行函数可以减少内存消耗

坏处

①其中一点上面已经有体现了,就是被引用的私有变量不能被销毁,增大了内存消耗,造成内存泄漏,解决方法是可以在使用完变量后手动为它赋值为null;

②其次由于闭包涉及跨域访问,所以会

“函数是不是闭包” 这种问题本身是不对的。虽然在网络上常见这种提法,但是其实是因为对 Javascript 实现机制不清楚胡乱猜测导致的误解。

首先,一个函数不管是不是匿名函数,和闭包之间根本没有任何关系!

所谓闭包究竟是什么?网络上说法云里雾里,讲得高深莫测,但是其实只要稍微有一些编译器实现机制的认识,就会知道闭包其实是非常简单的东西。

我们先来看看下面的代码:

function funcA() {

    var a = 1, b = 2

    return funcB()

    

    function funcB() {

        // 注意,a 和 b 在本函数里根本没有定义,但是竟然能访问到

        return a + b

    }

}

var a = funcA()

// a 将会等于 3

上面的代码神奇的地方有几点:

1、函数可以嵌套定义(而 C/C++ 就不行)

2、嵌套的函数可以访问到它的上级函数的局部变量

先说嵌套,其实这个能力没什么神奇的,C/C++ 编译器稍作修改就能支持,但是这么实现出来,虽然函数可以嵌套了,实用价值还是比较小,因为访问不到上级函数的局部变量啊。而且我们知道 Javascript 的嵌套函数是可以层层嵌套的,而访问时最内层的函数也能够访问到最顶层的函数的变量,非常有用!

说到这里,和闭包有什么关系呢?

闭包,就是用来实现这种嵌套时还能够层层向上访问变量的功能的!对的,它就是一个简单的编译器技巧,用来使得内部函数能够访问上级函数的变量。

简单来说,它具体实现的方法为,在每个函数上附加上一个额外的隐藏对象,这个对象其实就叫做闭包对象,你别管他名字怎么叫,它就是个普通的对象!它没什么神奇的,就是记录了本函数内部的变量列表而已。而且这个闭包对象还保存了一个指向上级函数的闭包对象的引用。

这样一来,就形成了一个链条。当我们在一个函数里访问一个变量的时候,编译器会先看看在本闭包里到底有没有这个变量,如果没有就向上寻找。如果找到,那就用,如果一直找到头也没有,那就提示出错。

明白了吗?就是这么回事。但是最后还有一点,按照上面的方式构造出来的闭包好像是固定的,其实每次调用一个函数的时候,都会单独创建一个新的闭包对象和这一次调用对应起来。因此其实闭包链是动态创建的。

其实要说清楚这个问题,得配几个图。但是时间所限,我就不细说了。如果你能理解那最好,如果还是有疑问,那你以后慢慢接触得多了就知道了。

最后解释一下这段代码,加深理解

function X() {

    return function() {

        // ...

    }

}

注意X里面这里返回了一个匿名函数。一定要记住这个函数由于是嵌套定义在 X 里的,因此它的闭包对象是链接到 X 的闭包对象上的,所以在这个匿名函数里是可以访问到 X 内部的变量的。其实就是这么简单。不管你嵌套多少层,匿名还是有名。我只看你定义时的嵌套关系,就知道闭包链的整个链条!其他就顺理成章了。

最后推荐两个让你走出国内普遍存在的误区的方法,一是多看 ECMA-262, 5e,这里面包含了所有标准化的 Javascript 的算法实现细节。另外一个是研究 Google 的 v8 引擎。自己下代码下来编译调试下,很多问题就能搞清楚了。

就说这么多了。

需要通过return的方式把要调用的函数返回给外部。

比如:

<script>

var ta = (function(){//定义一个闭包匿名函数。

return function(){//返回匿名函数内部的匿名函数给ta

alert('1')

}

})()

ta()//执行ta,弹出信息1

</script>

补充:

闭包是指有权访问另一个函数作用域中的变量的函数,创建闭包的最常见的方式就是在一个函数内创建另一个函数,通过另一个函数访问这个函数的局部变量。这种写法就是闭包的写法,闭包内部的函数如果不是return方式,在外部无法获取,无法进行调用。

扩展资料:

Function函数与Sub过程类似。但 Function函数可以有返回值。可以使用参数。如果 Function函数没有任何参数,则 Function语句必须要包含空括号。 Function函数通过函数名返回一个值。返回值的数据类型是Variant.

语法: Function 函数名 (参数1,参数2,...)

...

End Function

Function函数是包含在Function和End Function语句之间的一组VBScript语句。

参考资料来源:百度百科-Function函数