闭包 closure
1.变量的作用域
变量的作用域为全局变量和局部变量
Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量
var n=999;
function f1(){
alert(n);
}
f1();
在函数外部自然无法读取函数内的局部变量
function f1(){
var n=999;
}
alert(n);
在函数内部声明,必须用var 声明
var n=999;
function demo(){
console.log(n);
}
demo()
function func(){
var num=888;
}
console.log(num);
2.如何从外部读取局部变量?
在函数的内部,再定义一个函数。
function f1(){
var n=999;
function f2(){
alert(n);
}
return f2;
}
var result=f1();
result();
3.变量提升
function demo(){
//在函数内部声明变量的时候,如果未回 var 关键字,则函数运行后,该变量提升为全局变量
n="work hard at javascript"
}
demo()
console.log(n)
var name="I decide to"
var total=name+n
console.log(total)
4.闭包概念
将函数局部变量变成全局变量,连接函数内部和外部
5.闭包应用
function f1() {
var n = 999;
add = function() {
alert(n += 1);
}
function f2() {
alert(n);
}
return f2;
}
var result = f1();
result();
add();
result();
6.闭包思考题
1.The Window
var name ="The Window";
var object ={
name:"my object",
getNameFunc: function(){
return function(){
return this.name
};
}
};
alert(object.getNameFunc()());
2.my object
var name ="The Window";
var object ={
name:"my object",
getNameFunc: function(){
var that =this
return function(){
return that.name
};
}
};
alert(object.getNameFunc()());
7.闭包演示
结构:
<style type="text/css">
p {
background: lightblue;
}
</style>
</head>
<body onclick="init()">
<p>产品 0</p>
<p>产品 1</p>
<p>产品 2</p>
<p>产品 3</p>
<p>产品 4</p>
</body>
(1).
function init() {
var pAry = document.getElementsByTagName("p")
for (var i = 0
pAry[i].onclick = function() {
alert(i)
}
}
}
(2).
function init() {
var pAry = document.getElementsByTagName("p")
for (var i = 0
pAry[i].index=i
pAry[i].onclick = function() {
alert(this.index)
}
}
}
(3).
function init() {
var pAry = document.getElementsByTagName("p")
for (var i = 0
(pAry[i].onclick = function() {
alert(arguments.callee.i)
}).i=i
}
}
(4).
function init() {
var pAry = document.getElementsByTagName("p")
for (let i = 0
pAry[i].onclick = function() {
alert(i)
}
}
}
(5).
function init() {
var pAry = document.getElementsByTagName("p")
for (var i = 0
(function() {
var temp = i
pAry[i].onclick = function(){
alert(temp)
}
})()
}
}
8.闭包注意事项
1)由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。
解决方法是:
在退出函数之前,将不使用的局部变量全部删除。
2)闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。