闭包例题集

例1:

function a(){
	function b(){
		var bbb = 234;
		document.write(aaa);//123
	}
	var aaa = 123;
	return b;//a执行完前b被保存出来了
}
var glob = 100;
var demo = a();
demo();

预编译:
	a defined a.[[scope]] -->	0:GO{a:(function),glob:100,demo:(function)}
function a()开始运行:
	a handle  a.[[scope]] --> 	0:aAO{b:(function),aaa:123}
								1:GO的引用
return b后,b被定义:
	b defined b.[[scope]] --> 	0:aAO的引用
								1:GO的引用
function a()执行完毕,aAO中引用清空,但其中的属性b的引用已被返回给demo
function b()开始运行:
	b handle  b.[[scope]] --> 	0:bAO{bbb:234}
								1:aAO的引用
								2:GO的引用

例2:

function a(){
	var num = 100;
	function b(){
		num ++;
		console.log(num);
	}
	return b;
}
var demo = a();
demo();//101
demo();//102

预编译:
a defined a.[[scope]]-->	0:GO{a:(function),demo:(function)}
function a()开始执行:
a handle  a.[[scope]]-->	0:aAO{num:100,b(function)}
							1:GO的引用
return b,并将b赋值给demo
b defined b.[[scope]]-->	0:aAO的引用
							1:GO的引用
function a()执行完毕,将aAO的引用清空,但b任存在
function b()开始执行(执行2):
b defined b.[[scope]]-->	0:
							1:aAO的引用
							2:GO的引用

例3:

function test(){
	var arr = [];
	for(var i = 0; i< 10; i++){
		arr[i] = function(){
			document.write(i + " ");
		}
	}
	return arr;
}
var myArr = test();
for(var j = 0; j< 10; j++){
	myArr[j]();
}

test defined  test.[[scope]]--> 0:GO{test:(function),myArr:(function)}
test doing  test.[[scope]]-->	0:testAO{arr:[],i:0;myArr:(function)}
								1:GO的引用
arr[0]:function(){document.write(i + " ")};
arr[1]:function(){document.write(i + " ")};
....
arr[8]:function(){document.write(i + " ")};
arr[9]:function(){document.write(i + " ")};
return arr;   				
arr[j] defined arr[j].[[scope]]->0:testAO{arr:[],i:10;myArr:(function)}
								1:GO{test:(function),myArr:(function)}
arr[j] doing arr[j].[[scope]]->	0:{}
								1:testAO{arr:[],i:10;myArr:(function)}
								2:GO{test:(function),myArr:(function)}
arr[0]:function(){document.write(10 + " ")};
arr[1]:function(){document.write(10 + " ")};
....
arr[8]:function(){document.write(10 + " ")};
arr[9]:function(){document.write(10 + " ")};

例3 - 2:

//用闭包解决闭包的问题
// 立即执行函数被销毁之前,其上下文已经被里面的函数保存,
// 而且里面的函数整体也被保存到立即函数之外 
function test(){
	var arr = [];
	for(var i = 0; i< 10; i++){//运行10次立即执行函数
		//立即执行函数——用完即销毁。
		(function (j){//每个立即执行的函数都有一个对应的j
			arr[j] = function(){
			document.write(j + " ");
		}
		}(i));//i只有一个,但是j是随函数循环次数不断产生新的  
	}
	return arr;
}
var myArr = test();
for(var j = 0; j< 10; j++){
	myArr[j](j);
}
//0 1 2 3 4 5 6 7 8 9

例4:

// 使用原生js,addEventListener,给每个li元素绑定一个
// click事件,输出他们的顺序。
function test(){
		var liGroup = document.getElementsByTagName('li');
			for(var i = 0; i < liGroup.length; i++){
				(function(j){
					liGroup[j].onclick = function(){
						console.log(j);
					}
				}(i))	
			}	
		}
test();

闭包的运用①——累加器(更加结构化、模块化)

function add(){
	var count = 0;
	function demo(){
		count++;
		console.log(count);
	}
	return demo;
}
var counter = add();
counter();//1
counter();//2
counter();//3
counter();//4

闭包的运用②——缓存(存储结构)

function test(){
	var num = 100;
	function a(){
		num++;
		console.log(num);
	}
	function b(){
		num--;
		console.log(num);
	}
	return [a,b];
}
var myArr = test();
myArr[0]();
myArr[1]();

test defined test.[[scope]]--> 	0:GO{test:(function),myArr:(function)}
test handle  test.[[scope]]--> 	0:testAO{num:100,a:(function),b:(function)}
								1:GO的引用
return [a,b]后,function a()function b()被保存到myArr[]中
a defined a.[[scope]]-->	0:testAO的引用
							1:GO的引用
a handle  a.[[scope]]-->	0:aAO{}
							1:testAO的引用num:101=100+1
							2:GO的引用

b defined b.[[scope]]-->	0:testAO的引用
							1:GO的引用
b handle  b.[[scope]]-->	0:bAO{}
							1:testAO的引用num:100=101-1
							2:GO的引用
function eater(){
	var food = "";
	var obj = {
		eat : function(){
			console.log("i am eating " + food);
			food = "";
		},
		push :function(myFood){
			food = myFood;
		}
	}
	return obj;
}
var eater1 = eater();
eater1.push("apple");
eater1.eat();
//i am eating apple

闭包的运用③——私有化

function Deng(name,wife){
	this.name = name;
	this.wife = wife;
	var prepareWife = 'xiaozhang';
	this.divorce = function(){//divorce在外部执行怎么能用内部变量呢?
		this.wife = prepareWife;
	}
}
var deng = new Deng('deng','xiaoliu')
//deng.divorce();形成闭包,方法在对象上,对象被返回了,方法也被返回了
//该方法存储了Deng函数的执行上下文,所以能够获取prepareWife这个变量
//所以形成了这种局面:deng对象不能访问prepareWife,但deng的方法可以访问
//这样的闭包相当于是一个隐藏的区域,形成自己的私有变量
//所以你想看到这个变量,必须要调用其方法,否则无法访问
//这样的变量就相当于被对象私有化了,只有对象调用方法才能看到,外部想通过对象是看不到的

在这里插入图片描述
例5:

  • 求一个字符串的字节长度(提示:字符串有一个方法charCodeAt();一个中文占两个字节,一个英文占一个字节定义和用法)

版本1:

var str = window.prompt("input");
function retBytesLen(target){
	var count = 0;
	for(i = 0; i < str.length; i++){
		if(str.charCodeAt(i) <= 255){
			count += 1;
		}else{
			count += 2;
		}
	}
	document.write(count);
}
retBytesLen(str);

版本2:

var str = window.prompt("input");
function retBytesLen(target){
	var count = target.length;
	for(i = 0; i < target.length; i++){
		if(target.charCodeAt(i) > 255){
			count ++;
		}
	}
	document.write(count);
}
retBytesLen(str);

例6:,号操作符——返回最后的表达式结果
在这里插入图片描述

var f = (
	function f(){
		return "1";
	},
	function g(){
		return 2;
	}
)()
console.log(typeof(f));//number
var x = 1;
if(function f(){}){  //function f(){}在一个括号里就会变成立即执行函数,即这行运行完后,该函数就不存在
	x += typeof f;//typeof 一个未定义的变量不会报错,而是返回"undefined"
	//x = x + undefined -->NaN
	//x = x + "undefined" -->1undefined
}
console.log(x);//1undefined

例7:私有化变量

function Person(name,age,sex){
	var a = 0;
	this.name = name;
	this.age = age;
	this.sex = sex;
	function sss(){
		a++;
		document.write(a);
	}
	this.say = sss;
}
var oPerson = new Person();
oPerson.say();//1
oPerson.say();//2
var oPerson1 = new Person();
oPerson1.say();//1
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值