js学习笔记-闭包

时间:2022-01-05 22:44:32
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
</head>
<body>
<script>
//test
//闭包在Javascript中有多种应用场景和模式,比如Singleton,Power Constructor等这些Javascript模式都离不开对闭包的使用
//• 闭包就是函数的局部变量集合,只是这些局部变量在函数返回后会继续存在。

//• 闭包就是就是函数的“堆栈”在函数返回后并不释放,我们也可以理解为这些函数堆栈并不在栈上分配而是在堆上分配

//• 当在一个函数内定义另外一个函数就会产生闭包
//函数必须返回一个指向闭包的“引用”,或将这个”引用”赋值给某个外部变量,
//才能保证闭包中局部变量被外部代码访问。
//因为在Javascript中除了基本类型剩下的就都是对象了。

//1
function greeting(name) {
var text = 'Hello ' + name; // local variable
return function() {
alert(text);
} // 每次调用时,产生闭包,并返回内部函数对象给调用者
}
var sayHello=greeting("Closure");
sayHello()
//2
function Foo() {
var i = 0;
return function() {
console.log(i++);
}
}

var f1 = Foo(),
f2 = Foo();
f1();
f1();
f2();
//3
function buildList(list) {
var result = [];
for (var i=0; i<list.length; i++) {
var item = 'item' + list[i];
result.push( function() {alert(item + ' ' + list[i])} );
} // i=4;
return result;
}

function testList() {
var fnlist = buildList([1,2,3]); //将函数buildList赋给对象 fnlist,之后可以通过fnlist()方式调用该函数。item和i 不释放,形成闭包。
for (var j=0; j<fnlist.length; j++) {
fnlist[j](); //执行到这里时:alert('item3 4') index==4 指向undefined .length==3 执行三次
}
}
testList();//item3 undefined *3
//4
function newClosure(someNum, someRef) {

var num = someNum;
var anArray = [1,2,3];
var ref = someRef;
return function(x) {
num += x;
anArray.push(num);
alert(num+anArray.toString()+ref.someVar);
}
}
closure1=newClosure(40,{someVar:'closure 1'});
closure2=newClosure(1000,{someVar:'closure 2'});

closure1(5); // num:45 anArray[1,2,3,45] ref:'someVar closure1'
closure2(-10);// num:990 anArray[1,2,3,990] ref:'someVar closure2'
//5
function sayAlice() {
var sayAlert = function() { alert(alice); }
// Local variable that ends up within closure
var alice = 'Hello Alice';
return sayAlert;
}
var helloAlice=sayAlice();
helloAlice();
//6
function setupSomeGlobals() {
var num = 666;
gAlertNumber = function() { alert(num); }
gIncreaseNumber = function() { num++; }
gSetNumber = function(x) { num = x; }
}
setupSomeGolbals(); // 为三个全局变量赋值
gAlertNumber(); //666
gIncreaseNumber();
gAlertNumber(); // 667
gSetNumber(12);//
gAlertNumber();//12
//7
function say667() {
var num = 666;
var sayAlert = function() { alert(num); }
num++;
return sayAlert;
}

var sayAlert = say667();
sayAlert()
//8 单例模式下的闭包应用
</script>
</body>
</html>