什么是作用域?什么是自由变量?
作用域:变量的合法使用范围
全局作用域:在全局可以使用
函数作用域:只能在函数块中使用
块级作用域(ES6新增) : let,const定义的变量有块级作用域{}内部使用
自由变量:
1.—个变量在当前作用域没有定义,但是被使用了
2.向上级作用域,一层一层一次寻找,直到找到为止
3.如果到全局作用域都没找到,则报错:xxx is not defined
闭包(两种常见形式,自由变量的查找规则)
闭包:作用域应用的特殊情况,有两种表现:
1.函数作为返回值
⒉函数作为参数
闭包:
所有自由变量的查找,是在函数定义的地方,向上级作用域查找不是在函数执行的地方查找
this有几种赋值情况
this取什么值是在函数执行的时候确定的,不是在函数定义的时候确定的。
闭包-(自由变量)是在函数定义的时候确定的,不是在函数执行的时候确定的。
作为普通函数调用
使用 call apply bind 调用
作为对象方法被调用(普通调用,settimeout,箭头函数)
settimeout中的this:setTimeout()调用的代码运行在与所在函数完全分离的执行环境上。这会导致这些代码中包含的 this 关键字会指向 window (或全局)对象。setTimeout 中的函数是作为一个普通函数被执行的,一般这个函数的 this 就是 window 对象。
解决方法,使用箭头函数即可,如下图所示:
可以看出,如果直接在waitAgin()中打印this,this就指向当前对象。但this现在是在setTimeout()中触发的,setTimeout()不是对象方法。故会指向windows对象。但是现在有箭头函数。箭头函数永远取上级作用域的this。故会取到waitAgin()中的this,故为当前对象。
在class方法中调用
面试题
this的不同应用场景,如何取值?
手写bind函数
下面展示手写的bind函数
原生bind函数是定义在Function的原型上的,证据如下:
画图可表示为
实际开发中闭包的应用场景,举例说明
隐藏数据
做一个简单的cache工具
创建10个’‘标签,点击的时候弹出来对应的序号
如果这样写,i是全局作用域,针对所有的块,点击按钮每次都会输出10,所以要改变一下写法,如下:
RU
这样写,i就变成了块级作用域,每次执行for循环的时候都会创建一个i的块级作用域与事件进行绑定。如: