浅析js中的闭包

这篇具有很好参考价值的文章主要介绍了浅析js中的闭包。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


闭包指那些引用了另一个函数作用域中变量的函数,通常是在嵌套函数中实现的。

闭包形成的原理作用域链。只要是代码都一个作用域中,写在函数内部的局部作用域,未写在任何函数内部即在全局作用域中;如果函数中还有函数,那么在这个作用域中就又可以诞生一个作用域;根据在 [内部函数可以访问外部函数变量] 的这种机制,用链式查找决定哪些数据能被内部函数访问,就称作 作用域链就近原则

闭包带来的问题:由于垃圾回收器不会将闭包中变量销毁,于是就造成了内存泄露,内存泄露积累多了就容易导致内存溢出。

闭包会保留它们包含函数的作用域,所以比其他函数更占用内存。过度使用闭
包可能导致内存过度占用。

一般就是一个函数A,return其内部的函数B,被return出去的B函数能够在外部访问A函数内部的变量,这时候就形成了一个B函数的变量背包,A函数执行结束后这个变量背包也不会被销毁,并且这个变量背包在A函数外部只能通过B函数访问。

this对象

在闭包中使用 this 会让代码变复杂。如果内部函数没有使用箭头函数定义,则 this 对象会在运行时绑定到执行函数的上下文。如果在全局函数中调用,则 this 在非严格模式下等于 window,在严格模式下等于 undefined。如果作为某个对象的方法调用,则 this 等于这个对象。匿名函数在这种情况下不会绑定到某个对象,这就意味着 this 会指向 window,除非在严格模式下 this 是 undefined。不过,由于闭包的写法所致,这个事实有时候没有那么容易看出来。

window.identity = 'The Window'; 
let object = { 
	identity: 'My Object', 
	getIdentityFunc() { 
		return function() { 
			return this.identity; 
		}; 
	} 
}; 
console.log(object.getIdentityFunc()()); // 'The Window'
console.log(object.getIdentityFunc()); // ƒ () { return this.identity; }
window.identity = 'The Window'; 
let object = { 
	identity: 'My Object', 
	getIdentityFunc() { 
		let that = this;
		return function() { 
			return that.identity; 
		}; 
	} 
}; 
console.log(object.getIdentityFunc()()); // 'My Object'
console.log(object.getIdentityFunc()); // ƒ () { return that.identity; }

内存泄漏

在一些旧版本的 IE 中,把 HTML 元素保存在某个闭包的作用域中,就相当于宣布该元素不能被销毁。来看下面的例子:

function assignHandler() { 
	let element = document.getElementById('someElement'); 
	element.onclick = () => console.log(element.id); 
} 

以上代码创建了一个闭包,即 element 元素的事件处理程序。而这个处理程序又创建了一个循环引用。匿名函数引用着 assignHandler()的活动对象,阻止了对element 的引用计数归零。只要这个匿名函数存在,element 的引用计数就至少等于 1。也就是说,内存不会被回收。
只要这个例子稍加修改,就可以避免这种情况,比如:

function assignHandler() { 
	let element = document.getElementById('someElement'); 
	let id = element.id; 
	element.onclick = () => console.log(id);
	element = null; 
} 

修改后,闭包改为引用一个保存着 element.id 的变量 id,从而消除了循环引用。
不过,光有这一步还不足以解决内存问题。因为闭包还是会引用包含函数的活动对象,而其中包含element。即使闭包没有直接引用 element,包含函数的活动对象上还是保存着对它的引用。因此,必须再把 element 设置为 null。这样就解除了对这个 COM 对象的引用,其引用计数也会减少,从而确保其内存可以在适当的时候被回收。文章来源地址https://www.toymoban.com/news/detail-816712.html

到了这里,关于浅析js中的闭包的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 前端常见面试题之js基础(手写深拷贝、原型和原型链、作用域和闭包)

    值类型包括 :字符串(string)、数字(number)、布尔值(boolean)、undefined。 引用类型包括 :对象(object)、数组(array)、函数(function)和null。 二者的区别 当你将一个值类型赋给另一个变量时,会复制该值的副本。而当你将一个引用类型赋给另一个变量时,只会复制对

    2024年01月22日
    浏览(34)
  • SAP Fiori开发中的JavaScript基础知识15 - 原型,object,constructor,class,继承

    本文将介绍JavaScript中的核心概念 - 原型,并会介绍基于原型的应用场景object,constructor,class,继承。 本文会将这几个核心概念汇总在一篇博客中,因为这些概念是触类旁通的,希望对你有帮助。 在JavaScript中,几乎所有的东西都是对象,每个对象都有一个 特殊的内部属性

    2024年04月23日
    浏览(66)
  • 【前端知识】JavaScript——Symbol类型

    什么是Symbol(符号)类型? ​ Symbol是原始值,且Symbol实例是唯一、不可变的。Symbol的用途是确保对象属性使用唯一标识符,不会发生属性冲突的危险。Symbol创建唯一记号,进而用作非字符串形式的对象属性。 如何使用Symbol? 全局符号注册表 使用符号作为属性 常用内置符号

    2024年02月16日
    浏览(31)
  • Vue3+Vite前端知识汇总1篇

       目录 1、设置package.json,让编译完成后自动打开浏览器。 2、设置vite.config.ts,设置src别名,后面就不用 ../../../ 了。 3、安装@types/node  解决vscode显示红波浪线问题。  4、安装 sass和reset.css 5、创建并引入全局组件,HospitalTop 6、安装路由,并添加切换路由后滚动到顶部功能

    2024年02月16日
    浏览(30)
  • 前端HTML、CSS、JS、VUE3 汇总

    学习https://developer.mozilla.org/zh-CN/docs/Learn/CSS 提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 使用VS Code运行前端代码 在VS Code上安装前端插件 正在更新中~ ✨ 提示:这里可以添加本文要记录的大概内容: 学习路线 知识定位 HTML基础 标签、表格、表单、

    2024年02月13日
    浏览(40)
  • 学习Node.js需要哪些JavaScript知识

    Lexical Structure ( 词法 ) JavaScript 的词法(lexical grammar)。ECMAScript 源码文本会被从左到右扫描 ,并被转换为一系列的输入元素,包括 token、控制符、行终止符、注释和空白符。ECMAScript 定义了一些、字面量以及行尾分号补全的规则。 Expressions ( 表达式 ) JavaScript 中的

    2024年02月03日
    浏览(32)
  • 学习javascript,前端知识精讲,助力你轻松掌握

    ✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 所属专栏: 前端泛海 景天的主页: 景天科技苑 JavaScript在1995年诞生了; 由Netscape公司,布兰登·艾奇(Brendan Eich)发明的ECMAScript客户端脚本语言; 主要应用在浏览器,在当时却不温不火. 直到后来Netscape与S

    2024年03月15日
    浏览(53)
  • jQuery.js - 前端必备的Javascript库

    作者: WangMin 格言: 努力做好自己喜欢的每一件事 jQuery.js 是什么? jQuery是一个快速简洁、免费开源易用的JavaScript框架, 倡导写更少的代码,做更多的事情 。它封装JavaScript常用的功能代码,提供了一种简便的JavaScript设计模式,以及我们开发中常用到的操作DOM的API,优化HTML文

    2024年02月05日
    浏览(50)
  • 【前端知识】JavaScript——var 与 let 的区别

    var声明的变量会自动提升到函数作用域顶部,而let不会。 在解析代码时,JavaScript 引擎会注意出现在块后面的 let 声明,只不过在此之前不能以任何方式来引用未声明的变量。在 let 声明之前的执行瞬间被称为 暂时性死区(temporal dead zone) ,在此阶段引用任何后面才声明的变

    2024年02月16日
    浏览(34)
  • 2023年最新前端面试题汇总大全(含答案超详细,HTML,JS,CSS汇总篇)-- 持续更新

    专项练习–持续更新 HTML篇 CSS篇 JS篇 Vue篇 TypeScript篇 React篇 微信小程序篇 前端面试题汇总大全二(含答案超详细,Vue,TypeScript,React,微信小程序,Webpack 汇总篇)-- 持续更新 1.xhtml和html有什么区别 功能上 主要是 XHTML 可兼容各大浏览器、手机以及 PDA ,并且浏览器也能快速

    2024年02月12日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包