闭包和this指向问题
闭包
概念
MDN指出:
“在JavaScript中,每当创建一个函数,闭包便产生。”
“闭包是将函数与其引用的周边状态绑定在一起形成(封装)的组合”
阮一峰说:
闭包就是将函数内部和函数外部连接起来的一座桥梁。
闭包就是能够读取其他函数内部变量的函数
闭包只提供从内部到外部作用域的访问,而不能提供从外部到内部作用域的访问。
常见闭包
function outer() {
var a = 1
function inner() {
console.log(a) //1
}
inner() //或者是return inner,如果不 return,就无法使用这个闭包
//把 return inner 改成 window.inner = inner 也是一样的,只要让外面可以访问到这个 inner 函数就行了。
}
outer()
闭包的用途
它的最大用处有两个:
一个是前面提到的可以读取函数内部的变量
另一个就是让这些变量的值始终保持在内存中
闭包的注意点
1.由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。
2.闭包会在父函数外部,改变父函数内部变量的值。所以,如果把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。
this指向问题
举例
var obj = {
foo: function () { console.log(this.bar) },
bar: 1
};
var foo = obj.foo;
var bar = 2;
obj.foo() // 1
foo() // 2
对于obj.foo()来说,foo运行在obj环境,所以this指向obj;对于foo()来说,foo运行在全局环境,所以this指向全局环境。所以,两者的运行结果不一样。
说明
不同位置指向不同
函数体里面的this.x就是指当前运行环境的x
函数f在全局环境执行,this.x指向全局环境的
在obj环境执行,this.x指向obj.x
注意点
1.在没有对象的情况下调用this,此时this == undefined
2.一个函数在声明时,可能就使用了 this,但是这个 this 只有在函数被调用时才会有值。什么时候用this,才会
3.箭头函数没有 this,在箭头函数内部访问到的 this 都是从外部获取的,这个外部指的是环境变量中存储的this
4.this存储在环境记录(环境变量、执行上下文)中,环境记录是一个存储所有局部变量作为其属性的对象,包括this的值
补充
隐藏的关联对象
在js中,每个运行的函数、代码块以及整个脚本,都有一个被称为词法环境的内部的关联对象(也称是隐藏的关联对象)
而词法环境是有两部分组成的:
1.环境记录:是一个存储所有局部变量作为其属性的对象,包括this的值、
2.对外部词法环境的引用,这个是与外部代码相关联的一部分,类似于索引一样,而上者类似于值
隐藏属性
所有的函数在“诞生”时都会记住创建他们的词法环境,所有函数都有名为[[Environment]]的属性,该属性保存了对创建该函数的词法环境的引用
函数记住它创建于何处的方式,与函数被在哪调用无关
[[Environment]]引用在函数创建时被设置并永久保存
当调用某方法时,会为该调用创建一个新的词法环境,并且其外部词法环境引用获取于: 该方法.[[Environment]]
在JS中所有函数都是天生闭包的,JS中的函数会自动通过隐藏的[[Environment]]属性记住创建它们的位置,所以他们都可以访问外部变量
说明
var that = this;
在定义匿名函数之前,先把外部函数的 this 保存到变量 that 中,然后在定义闭包时,就可以让它访问 that,因为这是包含函数中名称没有任何冲突的一个变量。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?