函数闭包
函数表达式
函数声明:(函数声明提升)
function person(){}
函数表达式:(必须在调用之前声明)
var person = function(){}
递归函数:
一个函数通过名字调用自身
function fac (num) { // 阶乘递归
if (num <=1) {
return 1
} else {
return num*fac(num-1);
}
}
var a = fac;
fac = null;
console.log(a(4)) ; // 出错 因为fac在函数中调用自身时fac = null
为了做到松耦和:
非严格模式下使用argument.callee(指向正在执行的函数指针)来解决。
function fac (num) { // 阶乘递归
if (num <=1) {
return 1
} else {
return num*argument.callee(num-1); /
}
}
另一种方式:
var ff = (function f(num){
if (num <=1) {
return 1
} else {
return num*f(num-1); // 即使ff = null f(num-1)还是可以访问到
}
})
闭包:
定义:当一个函数内部定义了一个函数就创建了闭包,闭包有权访问包含函数内部的全部变量。
function a () {
var arr = [];
for (var i = 0,i < 4, i++) {
arr[i] = function () { // 闭包函数
return i;
}
}
}
console.log(a()) // [4,4,4,4]
原因是闭包函数中的i变量访问的是包含函数a中的i,循环中i的指向都是同一个i变量,等a()执行结束,i变量的值是10,所以返回的是[4,4,4,4]
解决:
function a () {
var arr = [];
for (var i = 0,i < 4, i++) {
arr[i] = function (num) { // 闭包函数
return num;
}(i); // 通过传值,每次返回的num都会是i的循环值
}
}
闭包的应用:
上例是一种应用,另一种应用:特权方法,(只能通过闭包函数访问包含函数的变量和方法)。
function Creat(){
var arr = [];
this.arrs = function (name) {
arr.push(name);
console.log(arr)
}
}
var a = new Creat()
a.arrs('zhang'); // zhang
a.arrs('ss') ; // zhang ss
闭包的原理:
在后台执行环境中,闭包包含着它自己的作用域、包含函数作用域、全局作用域。通常函数作用域及其所有变量都会在函数执行完毕后销毁,但是当函数返回一个闭包,函数作用域将会存在于内存中至到闭包销毁为止