美文网首页
js 闭包(面试题)

js 闭包(面试题)

作者: 洪锦一 | 来源:发表于2021-10-13 10:53 被阅读0次

我们首先知道闭包有3个特性:
①函数嵌套函数
②闭包就是能够读取其他函数内部变量的函数
③参数和变量不会被垃圾回收机制回收

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

function fn() {
    var name = "zs"
    return function () {
        return name;
    }
}
var fnn = fn();
console.log(fnn());//zs

2

function fun() {
    var num = 3;
    return function () {//匿名函数
        var n = 0;
        console.log(++n);
        console.log(++num);
    }
}
var f = fun();
f()//1 4
f()//1 5 

匿名函数作为fun的返回值被赋值给了f,
这时候相当于 f=function(){var n = 0 … },
并且匿名函数内部引用着fun里的变量num,所以变量num无法被销毁,
而变量n是每次被调用时新创建的,所以每次 f 执行完后它就把属于自己的变量连同自己一起销毁,
于是乎最后就剩下孤零零的num,于是这里就产生了内存消耗的问题

3. 定时器与闭包

//写一个for循环,让它按顺序打印出当前循环次数
for (var i = 0; i < 5; ++i) {
    setTimeout(function () {
        console.log(i + ' ');
    }, 1000)
}
// 按照预期它应该依次输出1 2 3 4 5,而结果它输出了五次5,这是为什么呢?
// 原来由于js是单线程的,所以在执行for循环的时候定时器setTimeout被安排到任务队列中排队等待执行,
// 而在等待过程中for循环就已经在执行,等到setTimeout可以执行的时候,for循环已经结束,i的值也已经变成5,
// 所以打印出来五个5,那么我们为了实现预期结果应该怎么改这段代码呢?(ps:如果把for循环里面的var变成let,也能实现预期结果)
    
for (var i = 0; i < 5; ++i) {
    (function (i) {
        setTimeout(function () {
            console.log(i + ' ');
        }, 1000)
    })(i)
}
// 引入闭包来保存变量i,将setTimeout放入立即执行函数中,将for循环中的循环值i作为参数传递,100毫秒后同时打印出1 2 3 4 5
// 那如果我们想实现每隔100毫秒分别依次输出数字,又该怎么改呢?
for (var i = 0; i < 5; ++i) {
    (function (i) {
        setTimeout(function () {
            console.log('100 * i', i);
        }, 100 * i)
    })(i)
}
// 在这段代码中,相当于同时启动3个定时器,i*100是为4个定时器分别设置了不同的时间,同时启动,
// 但是执行时间不同,每个定时器间隔都是100毫秒,实现了每隔100毫秒就执行一次打印的效果。

/**********************************②闭包作为参数传递*****************************************/
var num = 15;
var f1 = function (x) {
    if (x > num) {
        console.log('闭包作为参数传递', x);
    }
}

void function (f2) {
    var num = 100;
    f2(30)
}(f1)

//在这段代码中,函数 f1 作为参数传入立即执行函数中,在执行到f2(30)的时候,30作为参数传入fn1中,
// 这时候if(x>num)中的num取的并不是立即执行函数中的num,而是取创建函数的作用域中的num这里函数创建的作用域是全局作用域下,
// 所以

最后总结一下闭包的好处与坏处
好处
①保护函数内的变量安全 ,实现封装,防止变量流入其他环境发生命名冲突
②在内存中维持一个变量,可以做缓存(但使用多了同时也是一项缺点,消耗内存)
③匿名自执行函数可以减少内存消耗

坏处
①其中一点上面已经有体现了,就是被引用的私有变量不能被销毁,增大了内存消耗,造成内存泄漏,解决方法是可以在使用完变量后手动为它赋值为null;
②其次由于闭包涉及跨域访问,所以会

https://blog.csdn.net/weixin_43558749/article/details/90905723

相关文章

  • 好程序员web前端培训分享web前端面试题JS篇之闭包

    好程序员web前端培训分享web前端面试题JS篇之闭包,JS中关于闭包的相关知识。如果你想参加web前面工作,那么...

  • php之闭包函数(Closure)

    php闭包函数(Closure) JS闭包 js和php闭包使用和区别

  • JS闭包

    JS闭包 闭包练习

  • 前端面试必问总结

    前言 本文用于总结个人在工作期间总结的一些面试题 题目列表 js的函数声明 js的原型链 js的闭包 js的Pro...

  • 闭包1(基础)

    (什么是闭包?闭包的作用?闭包的缺陷?) (闭包的几种可能的应用场景) (闭包与内存泄漏,有关闭包的面试题) 推荐...

  • js闭包问题

    javascript 闭包的概念,闭包的作用,闭包经典面试题详解(配图解) 函数作用域(闭包前置知识) 要彻底弄懂...

  • JS闭包问题(二)

    在之前的JS闭包问题(一)文章中大概介绍了一下JS闭包,同时讲了闭包与变量之间的问题,今天我们继续聊闭包,聊聊闭包...

  • js 闭包(面试题)

    我们首先知道闭包有3个特性:①函数嵌套函数②闭包就是能够读取其他函数内部变量的函数③参数和变量不会被垃圾回收机制回...

  • 文摘-20170305

    前端 释义图例详解那道setTimeout与循环闭包的经典面试题js中proto和prototype的区别和关系?...

  • JS闭包大结局(JS闭包系列3)

    在上一篇中再谈JS闭包(JS闭包系列2),我详细的介绍了JS中的变量作用域相关的概念,结合第一节关于JS闭包(JS...

网友评论

      本文标题:js 闭包(面试题)

      本文链接:https://www.haomeiwen.com/subject/xdmsoltx.html