JS闭包原理、用处和使用是什么,基本模型有哪些
Admin 2022-09-14 群英技术资讯 386 次浏览
1.什么是闭包
闭包的含义就是闭合,包起来,简单的来说,就是一个具有封闭功能与包裹功能的结构。所谓的闭包就是一个具有封闭的对外不公开的,包裹结构,或空间。
在JS中函数构成闭包。一般函数是一个代码结构的封闭结构,即包裹的特性,同时根据作用域规则只允许函数访问外部的数据,外部无法访问函数内部的数据,即封闭的对外不公开的特性,因此说函数可以构成闭包。
概括:闭包就是一个具有封闭与包裹功能的结构。函数可以构成闭包。函数内部定义的数据函数外部无法访问,即函数具有封闭性;函数可以封装代码即具有包裹性,所以函数可以构成闭包。
函数就可以构成闭包,要解决的问题就是如何访问到函数内部的数据
function foo () { var num = 123; return num; } var res = foo(); console.log( res ); // =>123
这里的确是访问到函数中的数据了。但是该数据不能第二次访问,因此第二次访问的时候又要调用一次foo,表示又有一个新的num = 123出来了。
在函数内的数据,不能直接在函数外部访问,那么在函数内如果定义一个函数,那么在这个函数内部中是可以直接访问的
function foo() { var num = Math.random(); function func() { return mun; } return func; } var f = foo(); // f 可以直接访问这个 num var res1 = f(); var res2 = f();
我们使用前面学习的绘制作用域链结构图的方法来绘制闭包的作用域链结构图,如下:
如何获得超过一个数据
function foo () { var num1 = Math.random(); var num2 = Math.random(); return { num1: function () { return num1; }, num2: function () { return num2; } } }
如何完成读取一个数据和修改这个数据
function foo () { var num = Math.random(); return { get_num : function () { return num; }, set_num: function( value ) { return num = value; } } }
一般闭包的问题就是要想办法简洁的获取函数内的数据使用权,那么我们就可以总结出一个基本的使用模型。
闭包是为了实现具有私有访问空间的函数的
带有私有访问数据的对象
function Person() { this.name = "张三"; // setName( '' ) }
所有的私有数据,就是说只有函数内部可以访问的数据,或对象内部的方法可以访问的数据
最简单的实现:
function createPerson() { var __name__ = ""; return { getName: function () { return __name__; }, setName: function( value ) { // 如果不姓张就报错 if ( value.charAt(0) === '张' ) { __name__ = value; } else { throw new Error( '姓氏不对,不能取名' ); } } } } var p = createPerson(); p.set_Name( '张三丰' ); console.log( p.get_Name() ); p.set_Name( '张王富贵' ); console.log( p.get_Name() );
带有私有数据的函数
var func = function () {} function func () {} var foo = (function () { // 私有数据 return function () { // 可以使用私有的数据 ... }; });
对象模型
function foo () { // 私有数据 return { method : function(){ // 操作私有数据 } } }
函数模型
function foo(){ // 私有数据 return function(){ // 可以操作私有数据 } }
沙盘与盒子,就可以在一个笑笑的空间内模拟显示世界,特点是执行效果与现实世界一模一样,但是在沙箱中模拟与现实无关.
沙箱模式就是一个自调用函数,代码写到函数中一样会执行,但是不会与外界有任何的影响
例如,在jQuery中
(function () { var jQuery = function () { // 所有的算法 } // .... // .... jQuery.each = function () {} window.jQuery = window.$ = jQuery; })(); $.each( ... )
以 Fibonacci 数列为例,改进传统计算斐波那契数列方法
我们来回顾一下传统递归方式求斐波那契数列方法,我们定义一个count变量来查看递归了多少次:
var count = 0; function fibo( n ){ count++; if( n ==0 || n == 1 ) return 1; return fibo( n - 1 ) + fibo( n - 2 ); } fib1( 20 ); console.log( count1 ); // 5: 15 // 6: 25 // ... // 20: 21891
当 n = 5 式,count = 15,当时当 n = 20 的时候,count就达到惊人的21891次,性能太低了
性能低的原因是 重复计算。如果每次将计算的结果存起来
改进版:
var data = [ 1, 1 ]; var count = 0; function fibo( n ) { count++; var v = data[ n ]; if( v === undefined ){ v = fibo( n - 1 ) + fibo( n - 2 ); data[ n ] = v; } return v; } fibo( 100 ); console.log( count ); // 199
改进之后, n = 100的时候也才199次,大大提高了性能。
函数执行需要内存,那么函数中定义的变量,会在函数执行结束后自动回收,凡是因为闭包结构的,被引出的数据,如果还有变量引用这些数据的话,那么这些数据就不会被回收。
因此在使用闭包的时候如果不适用某学数据了,一定要赋值一个null
var f = (function () { var num = 123; return function () { return num; }; })(); // f 引用着函数,函数引用着变量num // 因此在不适用该数据的时候,最好写上 f = null;
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
React中useRef的用法有什么?如果有使用过React的朋友,应该对ref会比较熟悉的点,ref可以用来获取组件实例对象或者是DOM对象,而useRef这个hooks函数,除了传统的用法之外,它还可以“跨渲染周期”保存数据。那么具体怎样用呢?下面我们就一起来了解看看。
javascript中的math.random()是用来生成随机数的,其使用语法如“Math.floor(Math.random() * 10 + 1);”,该语句能在连续整数中取得一个随机数。
js替换字符串两端的空格,逗号,或其它任何的符号其实是很简单的,但为什么要在这儿讲呢?有一个问题是,如果字符串两端是一个或多个逗号,有可能只有一端有逗号,这种情况该怎么用正则表达式来解决呢? 下面我列举几种情况,例如将下面这些字符的两端符号去
在开发后台管理系统的时候,很多地方都要用到导出excel 表格,比如将table中的数据导出到本地,这篇文章主要给大家介绍了关于Vue导出Excel功能的相关资料,需要的朋友可以参考下
这篇文章主要为大家详细介绍了如何利用JavaScript语言实现导入导出excel文件的功能,文中的示例代码讲解详细,感兴趣的小伙伴可以了解一下
成为群英会员,开启智能安全云计算之旅
立即注册Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008