什么是作用域?什么是自由变量?

作用域:变量的合法使用范围
全局作用域:在全局可以使用
函数作用域:只能在函数块中使用
块级作用域(ES6新增) : let,const定义的变量有块级作用域{}内部使用
自由变量:
1.—个变量在当前作用域没有定义,但是被使用了
2.向上级作用域,一层一层一次寻找,直到找到为止
3.如果到全局作用域都没找到,则报错:xxx is not defined
image.png

闭包(两种常见形式,自由变量的查找规则)

闭包:作用域应用的特殊情况,有两种表现:
1.函数作为返回值
⒉函数作为参数
image.png
image.png
闭包:
所有自由变量的查找,是在函数定义的地方,向上级作用域查找不是在函数执行的地方查找

this有几种赋值情况

this取什么值是在函数执行的时候确定的,不是在函数定义的时候确定的。
闭包-(自由变量)是在函数定义的时候确定的,不是在函数执行的时候确定的。

作为普通函数调用

image.png

使用 call apply bind 调用

image.png
image.png
bind会返回一个新的函数去执行,新函数绑定this。

作为对象方法被调用(普通调用,settimeout,箭头函数)

image.png
settimeout中的this:setTimeout()调用的代码运行在与所在函数完全分离的执行环境上。这会导致这些代码中包含的 this 关键字会指向 window (或全局)对象。setTimeout 中的函数是作为一个普通函数被执行的,一般这个函数的 this 就是 window 对象。
解决方法,使用箭头函数即可,如下图所示:
image.png
可以看出,如果直接在waitAgin()中打印this,this就指向当前对象。但this现在是在setTimeout()中触发的,setTimeout()不是对象方法。故会指向windows对象。但是现在有箭头函数。箭头函数永远取上级作用域的this。故会取到waitAgin()中的this,故为当前对象。

在class方法中调用

image.png

面试题

this的不同应用场景,如何取值?

手写bind函数

image.png
下面展示手写的bind函数
原生bind函数是定义在Function的原型上的,证据如下:
image.png
画图可表示为
IMG_20211018_114842.jpg
IMG_20211018_163959.jpg

实际开发中闭包的应用场景,举例说明

隐藏数据

做一个简单的cache工具

image.png

创建10个’‘标签,点击的时候弹出来对应的序号

image.png
如果这样写,i是全局作用域,针对所有的块,点击按钮每次都会输出10,所以要改变一下写法,如下:
image.pngRU
这样写,i就变成了块级作用域,每次执行for循环的时候都会创建一个i的块级作用域与事件进行绑定。如:
image.png