web前端面试题汇总之JS闭包篇

2019-05-2820:49:38WEB前端开发Comments3,037 views字数 1745阅读模式

web前端面试题JS中关于闭包的相关知识。如果你想参加web前面面试,正在做面试准备,就来看一看小编今天为大家准备的文章吧!文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/13165.html

web前端面试题汇总之JS闭包篇文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/13165.html

说说你对闭包的认识文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/13165.html

“请讲一下你对闭包的认识”——这道题几乎是前端面试必问的问题,今天我试着总结一下如何优雅的回答这道题文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/13165.html

什么是闭包文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/13165.html

一句话解释:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/13165.html

能够读取其他函数内部变量的函数。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/13165.html

稍全面的回答:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/13165.html

在js中变量的作用域属于函数作用域, 在函数执行完后,作用域就会被清理,内存也会随之被回收,但是由于闭包函数是建立在函数内部的子函数, 由于其可访问上级作用域,即使上级函数执行完, 作用域也不会随之销毁, 这时的子函数(也就是闭包),便拥有了访问上级作用域中变量的权限,即使上级函数执行完后作用域内的值也不会被销毁。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/13165.html

这里涉及到对函数作用域的认识: js变量分为全局变量和局部变量;函数内部可以直接读取全局变量,而在函数外部自然无法读取函数内的局部变量文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/13165.html

闭包解决了什么问题文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/13165.html

1. 可以读取函数内部的变量文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/13165.html

2. 让这些变量的值始终保持在内存中。不会在函数调用后被清除文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/13165.html

可以通过下面的代码来帮助理解上面所说的:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/13165.html

function addCounter() {

let counter = 0

const myFunction = function () {

counter = counter + 1

return counter

}

return myFunction

}

const increment = addCounter()

const c1 = increment()

const c2 = increment()

const c3 = increment()

('increment:', c1, c2, c3);

// increment: 1 2 3

在这段代码中increment实际上就是闭包函数myFunction, 它一共运行了三次,第一次的值是1,第二次的值是2,第三次的值是3。这证明了,函数addCounter中的局部变量counter一直保存在内存中,并没有在addCounter调用后被自动清除。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/13165.html

闭包的应用场景文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/13165.html

在开发中, 其实我们随处可见闭包的身影, 大部分前端 JavaScript 代码都是“事件驱动”的,即一个事件绑定的回调方法; 发送ajax请求成功|失败的回调;setTimeout的延时回调;或者一个函数内部返回另一个匿名函数,这些都是闭包的应用。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/13165.html

下面是具体应用的例子:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/13165.html

1. 老掉牙的取正确值问题文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/13165.html

for (var i = 0; i < 10; i++) {

setTimeout(function () {

(i) //10个10

}, 1000)

}

怎么取到每一次循环的正确值呢? 闭包这样用:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/13165.html

for (var i = 0; i < 10; i++) {

((j) => {

setTimeout(function () {

(j) //1-10

}, 1000)

})(i)

}

声明了10个自执行函数,保存当时的值到内部文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/13165.html

2.使用闭包模拟私有变量文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/13165.html

私有变量在java里使用private声明就可以了, 但是在js中还没有,但是我们可以使用闭包模拟实现。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/13165.html

var counter = (function () {

var privateCounter = 0;

function changeBy(val) {

privateCounter += val

}

return {

increment: function () {

changeBy(1)

},

decrement: function () {

changeBy(-1)

},

value: function () {

return privateCounter

}

}

})();

() //0

() //1

() //2

() //1

匿名函数已经定义就立即执行, 创建出一个词法环境包含、、三个方法,还包含了两个私有项:privateCounter变量和changeBy函数。这两个私有项无法在匿名函数外部直接访问,必须通过匿名包装器返回的对象的三个公共函数访问。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/13165.html

闭包的缺点文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/13165.html

1. 由于闭包会是的函数中的变量都被保存到内存中,滥用闭包很容易造成内存消耗过大,导致网页性能问题。解决方法是在退出函数之前,将不再使用的局部变量全部删除。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/13165.html

2. 闭包可以使得函数内部的值可以在函数外部进行修改。所有,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/13165.html

  • 本站内容整理自互联网,仅提供信息存储空间服务,以方便学习之用。如对文章、图片、字体等版权有疑问,请在下方留言,管理员看到后,将第一时间进行处理。
  • 转载请务必保留本文链接:https://www.cainiaoxueyuan.com/gcs/13165.html

Comment

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定