闭包
学闭包的时候感觉很绕,看了很多帖子总是看不明白,后来看了一期js面试的视频,对闭包豁然开朗,在这里写一下心得。
闭包通常的形式是一个函数里面包含另外一个 函数,这里经常令人困扰的是作用域问题,要想分析对这个问题,要记住一点,自由变量的查找是在函数声明的时候查找,而不是在执行的时候,可能听着有点绕,看代码就很清楚了。
function create() {
const a = 100
return function() {
console.log(a)
}
}
const a = 200
const fn = create()
fn()
这里结果输出是100,原因就是fn()执行console.log(a)的时候,这个a是在哪里找的,还是那句话,自由变量的查找是在函数声明的时候查找,而不是在执行的时候,因此我们看到在声明这个函数的作用域里有一个a,而且等于100,所以输出100,和下面全局的a没有什么关系。
原理就是这样,可以找一下类似的题目看一下,都可以解决。
this指针
this指针情况比较多,但是并不是很难记,所以总结一下,梳理清条目,多看几遍就行。
this指针的情况有:
- 作为普通函数
- 使用call apply bind
- 作为对象方法
- 在class方法中调用
- 箭头指针调用
this有一句话很重要,那就是this取什么值是在函数执行的时候确定的,不是在函数定义的时候确定的
function fn() {
console.log(this)
}
fn() //window
fn.call({x : 1}) //{x : 1}
上述代码对应前两种情况,fn函数在全局window下面执行的,所以this指向 window ,运用call可以改变this指针,指向其中的参数,所以this指向了一个对象
const zhangsan = {
name: '张三',
say() {
console.log(this)
},
wait() {
setTimeout(function() {
console.log(this)
},1000)
}
}
zhangsan.say() //zhangsan
zhangsan.wait() //window
再看另外几种情况,class类里面的函数执行this,会指向函数本身所在作用域的对象,say()函数作用域在class内,所以指向class,而settimeout为全局函数,其作用域为window
最后一个为箭头函数,我们看一下例子
const zhangsan = {
name: '张三',
say() {
console.log(this)
},
wait() {
setTimeout(() => {
console.log(this)
},1000)
}
}
zhangsan.say() //zhangsan
zhangsan.wait() //zhangsan
这里将settimeout里面的函数改为箭头函数,指针又变成了zhangsan,原因就是箭头函数本身不改变this指针方向,它的this指针会和它父级作用域的this保持一致,本例中它的父级作用域为wait(),wait的this指针指向calss
基本就是 这几种情况,以后遇到对号入座分析就行