位置: 编程技术 - 正文

谈谈JavaScript中的函数与闭包(请问在javascript程序中)

编辑:rootadmin

闭包这东西,说难也难,说不难也不难,下面我就以自己的理解来说一下闭包

一、闭包的解释说明 对于函数式语言来说,函数可以保存内部的数据状态。对于像C#这种编译型命令式语言来说,由于代码总是在代码段中执行,而代码段是只读的,因此函数中的数据只能是静态数据。函数内部的局部变量存放在栈上,在函数执行结束以后,所占用的栈被释放,因此局部变量是不能保存的。

Javascript采用词法作用域,函数的执行依赖于变量作用域,这个作用域是在定义函数时确定的。因此Javascript中函数对象不仅保存代码逻辑,还必须引用当前的作用域链。Javascript中函数内部的局部变量可以被修改,而且当再次进入到函数内部的时候,上次被修改的状态仍然持续。这是因为因为局部变量并不保存在栈上,而是通过一个对象来保存。

决定使用哪个变量是由作用域链决定的,每次生成函数实例时,都会为之创建一个对象用来保存局部变量,并且把这个用于保存局部变量的对象加入作用域链中。不同函数对象可以通过作用域链关联起来。Javascript中所有函数都是闭包,我们不能避免“产生”闭包。

引用一张《Javascript高级程序设计》中的图来说明,虽然这张图并不完全说明所有情况。图中的activation object就是用于保存变量的对象。

简而言之,在Javascript中:

闭包:函数实例保存着在执行时所需要的变量的引用,而不会复制保存当时变量的值。(在Object C的实现中,我们可以选择保存当时的值或者是引用)

作用域链:解析变量时查找变量所在的方式,以var作为终止符号,如果链上一直没有var,则一直追溯到全局对象为止。

C#中的闭包特性是由编译器把局部变量转换成引用类型的对象成员实现的。

二、闭包的使用 下面通过一些具体例子来说明如何利用闭包这一特性:

1.闭包是在定义的时候产生的

function Foo(){ function A(){} function B(){} function C(){}}我们每次执行Foo()的时候,都有有A,B,C这三个函数实例(闭包)产生,当Foo执行完毕,生成的实例没有其他引用,因此会被当成垃圾随之销毁(不一定是马上销毁)。我们来证实一下作用域链是在函数定义时确定的,所以这里显示的应该是'local scope'

var scope = "global scope"; function checkscope() { var scope = "local scope"; function f() { return scope; } return f;}checkscope()()

同样道理:

(function(){ function A(){} function B(){} function C(){}}())上面的表达式执行完后也会有A,B,C这三个函数实例(闭包)产生,因为这是一个立即执行的匿名函数,这三个闭包只能产生一次。生成的闭包没有其他引用,因此会被当成垃圾随之销毁(不一定是马上销毁)。

我们之所以这么写,目地有两个

1.避免污染全局对象

2.避免多次产生相同的函数实例

对比下面两个例子,闭包是如何保存作用域链的:

function A(){} //比较省内存的写法,创建对象速度快,开销小 (function(prototype){ var name = "a"; function sayName () { alert(name); } function ChangeName() { name += "_changed" } prototype.sayName = sayName;//引用通过执行匿名函数产生的闭包,闭包只会产生一次 prototype.changeName = ChangeName; }(A.prototype)) var a1 = new A(); var a2 = new A(); a1.sayName(); a1.changeName(); a2.sayName();

--------------------------------------------------------------------------------

function B(){ //原型链比较短的做法,找到方法的速度快,但是比较耗内存,每次new 调用构造器都有2个函数实例和1个变量产生。 var name = "b"; function sayName () { alert(name); } function changeName() { name += "_changed"; } this.sayName = sayName;//引用闭包,每次调用函数B都会产生新的闭包 this.changeName = changeName; }//如果函数调用之前带有new关键字,则函数作为构造器使用。//本质上来说作为构造器和作为普通函数调用没区别。如果直接调用B(),那么this对象会绑定到全局对象,新生成的闭包会代替旧的闭包赋给全局对象的changeName和sayName属性上,因此旧的闭包会被当成垃圾回收。//如果作为构造器使用,new 关键字会生成一个新的对象(this指向这个新对象)并初始化这个新对象的sayName和changeName属性,因此每次生成的闭包都会因为有引用而保留下来。 var b1 = new B(); b1.sayName(); b1.changeName(); b1.sayName(); var b2 = new B(); b2.sayName(); b1.sayName();

三、泄漏问题:在编译语言中,函数体总在文件的代码段中,并在运行期被装入标志为可执行的内存区。事实上我们不认为函数自身会有生命周期。我们在大多数情况下会认为“引用类型的数据结构”具有生存周期和泄漏的问题,如指针、对象等。JavaScript中内存的泄漏本质上就是定义函数时生成的保存局部变量的对象因为存在引用而不被当成垃圾被回收。

1.存在循环引用

2.有些对象总不能销毁,如IE6在DOM中的内存泄漏,或者在销毁时不能通知到Javascript引擎,因此也就有些Javascript闭包总不能被销毁。这些情况通常是发生在Javascript宿主对象和Javascript中原生对象沟通不畅导致。

推荐整理分享谈谈JavaScript中的函数与闭包(请问在javascript程序中),希望有所帮助,仅作参考,欢迎阅读内容。

谈谈JavaScript中的函数与闭包(请问在javascript程序中)

文章相关热门搜索词:javascript的语句,简要说明javascript的作用,简述javascript,javascript以及javascript的作用,简要说明javascript的作用,简要说明javascript的作用,简要说明javascript的作用,javascript的理解,内容如对您有帮助,希望把文章链接给更多的朋友!

深入了解javascript中的prototype与继承 通常来说,javascript中的对象就是一个指向prototype的指针和一个自身的属性列表。javascript创建对象时采用了写时复制的理念。只有构造器才具有prototype

关于jQuery $.isNumeric vs. $.isNaN vs. isNaN 在jQuery中,有几种方式可以判断一个对象是否是数字,或者可否转换为数字。首先,jQuery.isNaN()在最新版本中已经被移除了(1.7之后),取而代之的是jQu

在Javascript中 声明时用"var"与不用"var"的区别 Javascript声明变量的时候,虽然用var关键字声明和不用关键字声明,很多时候运行并没有问题,但是这两种方式还是有区别的。可以正常运行的代码并不

标签: 请问在javascript程序中

本文链接地址:https://www.jiuchutong.com/biancheng/377670.html 转载请保留说明!

上一篇:Javascript的时间戳和php的时间戳转换注意事项(js实现时间)

下一篇:深入了解javascript中的prototype与继承(深入了解的高级表达)

  • 核定征收个体户个人经营所得税税率
  • 受票方与付款方不一致
  • 居民个人取得境内、境外所得,如何计算应纳税额?
  • 消费税的计算方法有哪三种
  • 出租划拨土地收费合法吗
  • 实际发放股票股利是什么意思
  • 开专用发票可以直接写加工费这个明细吗
  • 企业亏损结转年限举例说明
  • 工资代扣的工会经费怎么做账
  • 文化事业建设费减免政策
  • 已付款已收货但发票未到账务处理怎么做
  • 工业企业辅助生产费用的分配方法
  • 低值易耗品摊销借贷方向
  • 建筑业红字发票备注
  • 企业营改增后的会计处理有何变化
  • 工程在建期间土地的摊销如何处理
  • 公司账上的应收账款余额变为负数涉及什么税?
  • 报废 库存商品
  • 外籍人员劳务费税率表
  • 实收资本印花税减免税优惠政策2019
  • 出口佣金可以在企业所得税前扣除吗
  • 计提工资与发放工资
  • 公司制作小程序定金能放在图物资吗
  • 收购全资子公司的账务处理
  • 建材销售公司需要交哪些税
  • 业务招待费进项税额转出
  • 企业所得税季报怎么申报
  • 债券借贷业务属于表外业务吗
  • 购买转账支票费用
  • 库存现金的收支账务处理
  • 补缴公积金账务处理
  • win10鼠标在哪
  • 预付账款是负数有什么税收风险
  • 个税退手续费怎么申请
  • 收回已核销的坏账并入账
  • win11好用吗知乎
  • 技术转让所得的税收优惠
  • 海狸岛好玩吗
  • 长期待摊费用是非流动资产吗
  • php连接mysql数据库的几种方式及区别
  • php扫一扫识别代码
  • 股权转让完税证明要多少时间
  • timedatectl命令用法
  • 休产假期间社保个人部分怎么办
  • 小规模纳税人什么意思
  • 建筑工程价款结算
  • 其他免税销售额大于0免税性质代码
  • 企业初期面临的主要问题
  • 记账凭证错了
  • 2022最新款带采集功能抖音壁纸小程序源码
  • sql数据库移动
  • 资产损失税前扣除最新政策2021
  • 新公司成立后税务方面有哪些流程2023
  • 银行存款产生的利息收入
  • 财税人员岗位职责
  • 个人所得税要计入管理费用吗
  • 应交税费期末余额在借方怎样处理
  • 法院退诉讼费账务处理
  • 外币转入账户什么意思
  • 收到的发票怎么做分录
  • 收银系统入库入错了怎么办
  • 代销商品怎么开票
  • 公司注销后原有未使用的包装还可以用吗怎么办
  • 财务会计期末总结
  • mysql如何输入数据
  • CentOS6.7 mysql5.6.33修改数据文件位置的方法
  • mysql停不掉
  • vista升级选项灰色
  • 系统审核策略配置
  • mac系统的控制面板在哪
  • win8商店还能用吗
  • windows8.1默认壁纸
  • w10系统音频怎么设置
  • 安装网络设备
  • msn无法登录
  • js拖拽生成页面
  • 深入理解计算机系统 电子书
  • 税务机关文化建设
  • 北京24小时税务自助机
  • 什么是企业融资,什么是政府融资
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设