当内部函数被保存到外部时,将会生成闭包。闭包会导致原油作用域链不释放,造成内存占用。
// 练习题
function test(){
var arr = [];//定义一个数组,里面放10个function
for (var i = 0; i < 10; i++) {
arr[i] = function(){
document.write(i+" ");
}
}
return arr;//返回到外部
}
// 用myArr接收返回的数组
var myArr = test();//执行test函数 返回arr装了10个function
// 调用十个function
for (var j = 0; j < 10; j++) {
myArr[j]();//打印的10个都是10
}
// 解析:
test 定义 test.[[scope]]--->0:GO
test 执行 test.[[scope]]--->0:testAO {i:0}
1:GO
arr[i] 定义 arr[i].[[scope]]--->0:testAO
test 执行 test.[[scope]]--->0:testAO {i:0}-test的for循环执行完后->{i:10}
1:GO
返回arr 在外部执行 此时的i已经为10
arr[i] 执行 arr[i].[[scope]]--->0:arr[i]AO
1:testAO {i:10}
用立即执行函数解决这个闭包打印相同i的问题
function test(){
var arr = [];//定义一个数组,里面放10个function
for (var i = 0; i < 10; i++) {
(function(j){
arr[j] = function(){
document.write(j+" ");
}
}(i));
}
return arr;//返回到外部
}
// 用myArr接收返回的数组
var myArr = test();//执行test函数 返回arr装了10个function
// 调用十个function
for (var j = 0; j < 10; j++) {
myArr[j]();//打印的10个都是10
}
// 解析:
test 定义 test.[[scope]]--->0:GO
test 执行 test.[[scope]]--->0:testAO {arr:undefined,i:0}
1:GO
执行时 test.[[scope]]--->0:testAO {arr:undefined,i:0}
1:GO
执行立即执行函数--->立即执行函数的[[scope]]--->0:立即执行的AO{j:0}
1:testAO {arr[0]:undefined}
arr[0] 定义 arr[0].[[scope]]--->0:立即执行的AO{j:0}
1:testAO {arr[0]:function}
依次循环
arr[1] 定义 arr[1].[[scope]]--->0:立即执行的AO{j:1}
1:testAO {arr[0]:function}
test 执行 test.[[scope]]--->0:testAO {i:0}-test的for循环执行完后->{i:10}
1:GO
返回arr 在外部执行 此时的i已经为10 但是每个arr[j]里面的j是分别保存的123456789
arr[j] 执行 arr[j].[[scope]]--->0:arr[j]AO
1:立即执行的AO{j:1} 0-9
2:testAO {arr[0]:function}
// 通过闭包,建自己的私有属性。
function Person(name){
// 为了别人能访问属性,却无法看到、修改属性。
// 用var 在构造函数内部定义属性。
// 如果用this,别人可以随意修改
var money = 100;
this.name = name;
this.makeMoney = function(){
money++;
}
this.pay = function(){
money--;
}
// ---------------------------
// 当new实例化后。构造函数内部会隐性
// var this = {
// 里面有this上的属性或方法。这里只有两个方法
// makemoney() pay()
// }
// 在最后会隐性return this;
// 那么money会在Person的AO中保存,并且被传到外部。
// 于是在外部依然能访问到money。只是无法修改
}
// 当实例化对象时 让他可以通过方法,使money增减。
// 却无法看到我的money,也无法直接修改money
var person = new Person();