官方对闭包的解释是:一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。
一、javascript闭包的特点:1.作为一个函数变量的一个引用,当函数返回时,其处于激活状态。
2.一个闭包就是当一个函数返回时,一个没有释放资源的栈区。
简单的说,javascript允许使用内部函数---即函数定义和函数表达式位于另一个函数的函数体内。而且,这些内部函数可以访问它们所在的外部函数中声明的所有局部变量、参数和声明的其他内部函数。当其中一个这样的内部函数在包含它们的外部函数之外被调用时,就会形成闭包。
二、javascript闭包的原理
闭包是指有权访问另一个函数作用域中的变量的函数。根据下面的代码示例来理解什么是闭包,在add函数内部的匿名函数中,访问到外部函数的变量outerArg,在执行add(10)之后外部函数返回了,并且将内部的匿名函数赋值给了变量addTen,此时通过addTen调用函数,依然可以访问到outerArg,也就是10。这个闭包中的变量,只能通过调用addTen函数访问,无法通过其他渠道访问到,下面代码最后一行通过输出属性的方式尝试访问结果是输出undefined。
outerArg是属于add函数的作用域中的变量,addTen有权访问add函数作用域中的变量,因此addTen是一个闭包。闭包产生的本质是:在一个函数(外部函数)内部定义的函数(内部函数)会将外部函数作用域中的活动对象添加到自己的作用域链中,下面代码中inner函数将add函数的outerArg添加到自己的作用域链上。在add函数执行完之后,其执行环境会被销毁,但由于inner函数还在引用outerArg,所以outerArg不会被销毁,依然保留在inner函数的作用域链中。直到inner函数(addTen函数)被销毁之后,outerArg才会跟着其作用域链一起被销毁。由于闭包变量是位于作用域链上,因此必须调用闭包函数进入其作用域之后才能访问到闭包变量。
funcTIon add(outerArg) {
funcTIon inner(innerArg) {
return innerArg + outerArg;
}
return inner;
}
var addTen = add(10);
console.log(addTen(1)); // 输出11
console.log(addTen(2)); // 输出12
console.log(addTen(3)); // 输出13
console.log(addTen.outerArg); // undefined123456789101112
三、javascript闭包的应用javascript闭包的应用1:
这个是我在用js模拟排序算法过程遇到的问题。我要输出每一次插入排序后的数组,如果在循环中写成
setTImeout(funcTIon() { $(“proc”).innerHTML += arr + “《br/》”; }, i * 500);
会发现每次输出的都是最终排好序的数组,因为arr数组不会为你保留每次排序的状态值。为了保存会不断发生变化的数组值,我们用外面包裹一层函数来实现闭包,用闭包存储这个动态数据。下面用了2种方式实现闭包,一种是用参数存储数组的值,一种是用临时变量存储,后者必须要深拷贝。所有要通过闭包存储非持久型变量,均可以用临时变量或参数两种方式实现。
《!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”》
《html xmlns=“http://www.w3.org/1999/xhtml”》
《head》
《title》《/title》
《script type=“text/javascript”》《!--
var arr = [4, 5, 6, 8, 7, 9, 3, 2, 1, 0];
var $ = function(id) { return document.getElementById(id); }
var Sort = {
Insert: function() {
for (var i = 1; i 《 arr.length; i++) {
for (var j = 0; j 《 i; j++) {
if (arr[i] 《 arr[j]) {
arr[i] = [arr[j], arr[j] = arr[i]][0];
}
}
setTimeout((function() {
var m = [];
for (var j = 0; j 《 arr.length; j++) {
m[j] = arr[j];
}
return function() {
$(“proc”).innerHTML += m + “《br /》”;
}
})(), i * 500);
//or 写成下面这样也可以
/*
setTimeout((function(m) {
return function() {
$(“proc”).innerHTML += m + “《br /》”;
}
})(arr.join(“,”)), i * 500);
*/
}
return arr;
}
}
// --》《/script》
《/head》
《body》
《div》
var a = [4, 5, 6, 8, 7, 9, 3, 2, 1, 0];《/div》
《div》
《input type=“button” value=“插入排序” onclick=“Sort.Insert();” /》
《/div》
Proc:《br /》
《div id=“proc”》
《/div》
《/body》
《/html》
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)