前言
学习了这么久前端,发现自己对于基础知识的掌握并没有那么通透,于是打算重新学一遍JS,借用经济学的一句话:JS基础决定能力高度🤦🏻
基础很重要,只有基础好才会很少出 bug,大多数的 bug 都是基础不扎实造成的
今天我们来看一下闭包与作用域
闭包与作用域可以说是JS基础中的基础,工作的时间久了发现自己连这两个知识点也差不多快忘了😭,于是打算重新学习下
从一道题说起
JS函数结果缓存
写一个函数memorize,实现以下需求
前提: 可以保证被缓存函数一定有返回值(非undifined)
1.缓存函数执行结果
例子:function getRandom(params) { return parseInt(Math.random() * 10 + params) } const getMemeResult = memorize(getRandom) getMemeResult(1) // 3 假设getResult2第一次执行结果为3 getMemeResult(2) // 5 重新执行getResult2得到结果为5 getMemeResult(1) // 3 getMemeResult(2) // 5 function memorize(fn){ /* coding here */ }
大家看到这道题有什么想法?
好了先按下解题冲动,先跟着我一起来学下闭包,当你学完闭包后你就会发现思路打开了,会发现题目原来轻而易举。
什么是闭包?
闭包(closure)是一个函数以及其捆绑的周边环境状态(lexical environment,词法环境)的引用的组合。换而言之,闭包让开发者可以从内部函数访问外部函数的作用域。在 JavaScript 中,闭包会随着函数的创建而被同时创建。
其实在JavaScript中闭包无处不在,你只需要能够识别并拥抱它,很多时候你的代码里写了很多的闭包,但是你自己也没有意识到,比如
function wait(message, time) {
setTimeout(() => {
console.log(message)
}, time * 1000)
}
wait('hello, closure', 1)
这就是我们日常使用中的闭包,或许你会觉得很奇怪,为啥这也是闭包啊?
我们知道闭包就是可以从内部函数访问外部函数的作用域,所以这里我们得先学习一下什么是作用域以及作用域的功能是什么。
作用域?
作用域是根据名称查找变量的一套规则,通俗来讲就是在执行代码阶段如何找到这个变量的一套法则。
举个例子🌰
function add(b) {
return a + b;
}
const a = 2;
add(3);
- 这段代码执行时会在全局作用域内声明函数
add
函数、变量a
,然后在执行add
函数 - 在
add
函数内,引擎会问add
作用域,是否存在a
add
作用域说没听过,你去问问别人吧- 于是引擎继续从
add
的作用域往上查找,发现找到全局作用域,于是问全局作用域是否有见过a
,我需要使用它 - 全局作用域说,在我这里