php 闭包函数递归,函数表达式 递归 闭包

函数声明

function dome(name) {

//函数体

}

关于函数声明,它的一个重要特性就是函数声明提升,意思就是在执行代码之前会先读取函数声明。这就意味着可以吧函数声明放在调用它的语句后边。

函数表达式

var dome = function(name) {

//函数体

}

这种形式看起来就像是常规的变量赋值语句,语法赋值内容也叫做匿名函数,所以说和变量一样使用前需要先赋值。

递归

递归函数是在一个函数中通过函数名调用自身的情况下构成的。

arguments.callee

返回正被执行的 Function对象,也就是所指定的Function对象的正文,这有利于匿名函数的递归或者保证函数的封装性。

使用arguments.callee替代函数名的引用,这样无论引用函数时使用的是什么名字,都可以保证正常完成递归调用。

现在已经不推荐使用arguments.callee();因为访问arguments是个很昂贵的操作,因为它是个很大的对象,每次递归调用时都需要重新创建。影响现代浏览器的性能,还会影响闭包。不过可以使用命名函数表达式来达成相同的结果。列如:

//严格模式下使用这个属性也会导致错误

var factorial = (function f(num) {

if(num <= 1){

return 1;

} else {

return num * f(num-1);

}

});

以上代码中即便把赋值给另外一个变量,也不会影响f(),是f依然有效。

闭包

闭包是指有权访问另一个函数作用域中变量的函数。

一般来讲,当函数执行完毕后,局部活动对象就会被销毁,内存中只保存全局作用域。

function outer() {

var a = '变量1'

var inner = function () {

console.info(a)

}

return inner

// inner 就是一个闭包函数,因为他能够访问到outer函数的作用域

}

var inner = outer() // 获得inner闭包函数

inner() //"变量1"

当程序执行完 var inner=outer(),其实outer的执行环境并没有被销毁,因为他里面的变量a仍然被inner的函数作用域链所引用,当程序执行完inner(),这时候,inner和outer的执行环境才会被销毁调。

function f1(){

var s = '嘤嘤嘤';

function f2(){

alert(s);

}

return f2;

}

var result=f1();

result(); // 嘤嘤嘤

因为Javascript语言特有的"链式作用域"结构(chain scope),子对象会一级一级地向上寻找所有父对象的变量。 所以 f2 可以读取 f1 中的局部变量,那么只要把 f2 作为返回值,我们就可以在 f1 外部读取它的内部变量。

function f1(){

var n=999;

var nAdd = ()=> {

n+=1

}

function f2(){

alert(n);

}

return f2;

}

var result=f1();

result(); // 999

nAdd();

result(); // 1000

在这段代码中,result实际上就是闭包f2函数。它一共运行了两次,第一次的值是999,第二次的值是1000。这证明了,函数f1中的局部变量n一直保存在内存中,并没有在f1调用后被自动清除。

为什么会这样呢?原因就在于f1是f2的父函数,而f2被赋给了一个全局变量,这导致f2始终在内存中,而f2的存在依赖于f1,因此f1也始终在内存中,不会在调用结束后,被垃圾回收机制(garbage collection)回收。

注意!

由于闭包会携带包含它的函数的作用域,因此会比其他函数占用更多内存。过度使用会使内存消耗很大造成网页性能问题,在IE中可能导致内存泄露。

闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值