zoukankan      html  css  js  c++  java
  • 闭包

    闭包:函数 A 内部有一个函数 B,函数 B 可以访问到函数 A 中的变量,那么函数 B 就是闭包。一个作用域可以访问另外一个函数的局部变量。

    闭包的作用:1.可以读取函数内部的变量,延长变量的作用域  2.让这些变量始终保持在内存中,即闭包可以使得它诞生环境一直存在

    1 function A() {
    2     let a = 1
    3     window.B = function() {
    4         console.log(a)
    5     }
    6 }
    7 A()
    8 B() // 1

    这里B就是闭包,单纯地说闭包就是函数嵌套了函数,然后返回一个函数,是不完整的,上面的例子很好地反驳了。

     1 function f1() {
     2     let a = 1
     3 
     4     function f2() {
     5         console.log(a);
     6     }
     7     return f2;
     8 }
     9 var res = f1();
    10 res(); // 1

    这里闭包就是函数f2,能够读取f1函数内部的变量(闭包就是一个能读取其他函数内部变量的一个函数,简单来说就是一个函数)

    1 function create(start) {
    2     return function() {
    3         console.log(start++);
    4     }
    5 }
    6 var inc = create(5);
    7 inc(); // 5
    8 inc(); // 6
    9 inc(); // 7

    这里就是闭包使得内部变量记住了上一次调用的结果。

    经典面试题,循环中使用闭包解决 `var` 定义函数的问题

    1 for (var i = 0; i < 6; i++) {
    2     setTimeout(function timer() {
    3         console.log(i);
    4     }, i * 1000)
    5 }

    首先因为 setTimeout 是个异步函数,所以会先把循环全部执行完毕,这时候 i 就是 6 了,所以会输出一堆 6。(同理,click等点击事件是回调函数,for循环是同步任务,就会先把循环执行完毕)

    解决办法有三种,第一种是使用闭包的方式

    1 for (var i = 0; i < 6; i++) {
    2     (function(j) {
    3         setTimeout(function timer() {
    4             console.log(j);
    5         }, j * 1000)
    6     })(i)
    7 }

    在上述代码中,我们首先使用了立即执行函数将 i 传入函数内部,这个时候值就被固定在了参数 j 上面不会改变,当下次执行 timer 这个闭包的时候,就可以使用外部函数的变量 j,从而达到目的。

    第二种就是使用 setTimeout 的第三个参数,这个参数会被当成 timer 函数的参数传入。

    1 for (var i = 0; i < 6; i++) {
    2     setTimeout(function timer(j) {
    3         console.log(j);
    4     }, i * 1000, i)
    5 
    6 }

    第三种就是使用 let 定义 i 了来解决问题了,这个也是最为推荐的方式

    1 for (let i = 0; i < 6; i++) {
    2     setTimeout(function timer() {
    3         console.log(i);
    4     }, i * 1000)
    5 }
  • 相关阅读:
    0841. Keys and Rooms (M)
    0478. Generate Random Point in a Circle (M)
    0714. Best Time to Buy and Sell Stock with Transaction Fee (M)
    0535. Encode and Decode TinyURL (M)
    1721. Swapping Nodes in a Linked List (M)
    0823. Binary Trees With Factors (M)
    1461. Check If a String Contains All Binary Codes of Size K (M)
    0623. Add One Row to Tree (M)
    1332. Remove Palindromic Subsequences (E)
    0706. Design HashMap (E)
  • 原文地址:https://www.cnblogs.com/helloCindy/p/12268891.html
Copyright © 2011-2022 走看看