1.闭包的概念
简单的理解就是函数中套了一个函数,内层函数可以访问外层函数中的变量,而外层函数不能访问内层的变量
闭包的情况一般有两种一个是作为参数被传递,作为返回值被返回出去
// 函数作为返回值
function create() {
const a = 100
return function () {
console.log(a)
}
}
const fn = create()
const a = 200
fn() // 100
// 函数作为参数被传递
function print(fn) {
const a = 200
fn()
}
const a = 100
function fn() {
console.log(a)
}
print(fn) // 100
函数中的自由变量,取决于函数定义的地方,跟执行的地方没关系
2.说到闭包不得不说一下this指向的问题
this五大应用场景
普通函数、
对象方法、
call apply bind
class
箭头函数
普通函数中
function fn(){
console.log(this);
}
fn(); //相当于下面的window.fn();
window.fn();
//普通函数this指向window
对象方法中
let pox={
name:'小红',
run:function(){
console.log(this.name)//this
}
}
pox.run();// pox 小红
//对象中this指向调用它的父级对象
call() /apply() /bind() 都可以改变this指向
let obj={name:'小明'}
let pox={
name:'小红',
run:function(){
console.log(this.name)
}
}
// 对象方法中的this.指向方法的调用者。
pox.run();// pox 小红
pox.run.call(obj)// 小明
pox.run.apply(obj);// 小明
pox.run.bind(obj)();//小明
相同点:call() /apply() /bind() 都可以改变this指向,指向第一个参数
不同点:bind()需要手动执行
class中的this
class Person{
constructor(name,age){
this.name=name;
this.age=age
}
say(){
console.log(`我叫${this.name}年龄是${this.age}`)
}
}
let lsy=new Person('李士乐',21);
lsy.say();// 我叫李士乐年龄是21
console.log(lsy);// {name:'李士乐',age:21}
class中的this指向new 后的实例对象
箭头函数中的this
let obj={name:'小明'}
var name='杨志' //不能用let声明,不存在变量提升
let pox={
name:'小红',
run:()=>{
console.log(this.name)//this
}
}
// 对象方法中的this.指向方法的调用者。
pox.run();// 杨志
pox.run.call(obj)// 杨志
pox.run.ally(obj);// 杨志
pox.run.bind(obj)();//杨志
class中的 this时刻指向父级的上下文对象。并且不可以被 call()/apply()/bind()修改。