初学者跪着学JavaScript Day23 : 闭包简单用

主要学习闭包使用,因为自己不太熟悉闭包使用方式所以趁这次铁人赛试着拿闭包来实作,在进到实作之前会简单介绍闭包

要先知道scope作用域:

w3school:Scope determines the accessibility (visibility) of variables.

范围内是否有存在的变数

闭包

mdn:

中文:闭包(Closure)是函式以及该函式被宣告时所在的作用域环境(lexical environment)的组合
英文:
A closure is the combination of a function bundled together (enclosed) with references to its surrounding state (the lexical environment). In other words, a closure gives you access to an outer function’s scope from an inner function. In JavaScript, closures are created every time a function is created, at function creation time.

为什麽这麽说?
在还没执行函式会先定义lexical environment(scope) ,在执行函式时会出现stack 里的execution context 内,到时会到scope去找要使用的变数,如果自己scope没有找到该变数的话就会往外层scope找寻,

闭包就是函式执行完後在stack里的execution context 消失,当函式内还有内部函式,内部函式会保留对父层scope的参照

scope找变数

每个function会有自己的scope

function school() {
    let teacher = 'maggie';
    function student() {
        console.log(teacher);
    }
    student();
}
school();//maggie

理解如何找变数:
内层function可以找到外层function 变数teacher,原因是自己的scope找不到变数,会往外层找变数teacher

举个例子:
假如我要

5+10
5+20
5+30

 function add5(x) {
     return x + 5;
 }
 console.log(add5(10));//15
 console.log(add5(20));//25
 console.log(add5(30));//35

每次执行函式时回传值都会加5
那要如何使用闭包达到这个效果呢?

闭包方式:

最基本使用方式:外部function return内部function

巢状函式

函式内的返回值是function
在add51变数保留对父层scope的参照
如下:

function addY(x) {
    return (y) => x + y;
}
let add5 = addY(5);
console.log(add5(10));//15
console.log(add5(20));//25
console.log(add5(30));//35

当返回值是一个物件时

如下:

function addx(x) {
    return {
        go: (y) => x + y,
    };
}
let add5 = addx(5);
console.log(add5.go(10));//15
console.log(add5.go(20));//25
console.log(add5.go(30));//35

进阶使用:

return 里面放一个物件,该物件内放各种方法,这方法叫闭包私有化

如下:
创建没有除法的计算机

function calculator() {
    let set = 0;
    return {
        add: (y) => (set += y),
        sub: (y) => (set -= y),
        mul: (y) => (set *= y),
    };
}

let myCalculator = calculator();

console.log(myCalculator.add(1));//1
console.log(myCalculator.add(2));//3
console.log(myCalculator.add(3));//6
console.log(myCalculator.add(4));//10
console.log(myCalculator.mul(4));//40

return一个物件里面放对set变数计算的methods

科里化(Currying)

科里化:接受多个参数的函数变换成接受一个单一参数

function add(a, b, c) {
    return a + b + c;
}

console.log(add(10, 20, 30));//60

let add = (number1) => (number2) => (number3) => {
    return number1 + number2 + number3;
};
let x = add(10);
let y = x(20);
let z = y(30);

console.log(z);//60

注意:一开始学习比较容易搞混的地方

function counter(){
  var count = 100 //在外部函式中宣告变数和内部函式;
  return function(){//在外部函式内返回内部函式;
    return ++count  //使用内部函式访问或者修改变数值
  }
}

//一个括号不会执行到内嵌的函式
console.log(counter()) // 印出funciton

//使用两个括号会重新整个执行一次
console.log(counter()()) // 印出100
console.log(counter()()) //印出100

//闭包
 const go = counter()
 console.log(go()) //印出 101
 console.log(go()) //印出 102
 console.log(go()) //印出 103
 console.log(go()) //印出 104


https://javascript.plainenglish.io/closures-in-javascript-37182198dc20
mdn


<<:  Day 23 中场休息,来做点酷东西(完成了呜呜)

>>:  感受时间的亲戚,时间、目标、精力三管

[面试]准备好要询问公司的问题,面试就是资讯战!

打着「吃亏就是占便宜」的口号,许多人别说去争取不属於自己的东西,连属於自己的东西都没有开口的勇气。...

Day 24 CSS3 < 过渡 transition>

过渡 (transition) 是可以在不使用Flash动画或JavaScript的情况下,当元素从...

CMoney菁英软件工程师战斗营前端课程_Week 11

Hi 本周已开始分领域课程 第一堂课不外乎就是介绍基本HTML语法 每周四都会有个小演习 这次题目是...

[DAY16] 实战 Azure Machine Learning RBAC

DAY16 实战 Azure Machine Learning RBAC 我们今天就来实战 RBAC...

[Day25] HTB Granny

URL : https://app.hackthebox.eu/machines/14 IP : ...