闭包:抽象来说内部函数被保存到外部时,就会生成闭包。
闭包会导致原有的作用域链不被释放,造成内存泄漏
(作用域链不释放,内存占用,内存占用的越多,内存就越小,就像内存泄漏了一样)
function a() {
function b() {
var bb = 123;
console.log(aa);
}
var aa = 123;
return b;
}
var glob = 100;
var demo = a(); //demo = b();
demo(); //执行 b;
* a执行产生两个 一个go{};一个ao{};
* b(被保存到了函数外部)定义时候引用的是a产生的两个go{},ao{},产生了闭包;
*a执行完,并不会销毁a的作用域,因为b还在用着;
*作用:实现共有变量,eg:函数累加器;可以做缓存(存储结构);可以实现封装,属性私有化,
模块化开发防止污染全局变量;
//累加器:
function add(){
var count = 0;
function demo(){
count ++;
console.log(count);
}
return demo;
}
var nihao=add();
nihao();
nihao();
nihao();
//缓存:
function eater() {
var food = ''; //隐式的存储结构
var obj = {
eat:function () {
console.log('我爱吃'+food);
food = '';
},
push:function (myfood) {
food = myfood;
}
}
return obj;
}
var aichi=eater();
aichi.push('pingguo');
aichi.push('juzi');
aichi.eat();
//立即执行函数(也可以有名字,参数,返回值,预编译,不过名字会被忽略,执行完就释放);
function zizhixing() { //正常函数声明,等待被执行 占用空间;
}
//针对初始化的函数,只执行一次,就用理解执行函数(执行完立即释放);
(function () {
console.log(123+456);
})();
var numss=(function (a,b) {
console.log(a+b);
return a+b;
})(1,3);
console.log(numss);
//两种写法
(function () {}()); // w3c 建议这种
// functi1on buenng() { 函数声明
// console.log('bunnegzhixing');
// }();
var tes=function buenng() { //函数表达式 ,所以这边可以被执行;能被执行符号执行的表达式基本是立即执行函数
,那么这个函数的名字就会被忽略;
console.log('bunnegzhixing');
}()
//只要是表达式就会被()执行;加上正号,负号,&&,||,!都会使函数成为表达式;
(function test(){console.log('a')});
function nihaoss() {
var arr=[];
for(var i=0;i<10;i++){
arr[i]=function () {
document.write(i+' '); //i等于10的时候 for循环结束;
}
}
return arr;
}
var arrs=nihaoss();
console.log(arrs); //此时i=10; 闭包出来他们用的是同一个go,ao;
for(var j=0;j<arrs.length;j++){
arrs[j](); //打印10
}
function bibaojiejue() {
var arr=[];
for(var i=0;i<10;i++){ //10个立即执行函数,每次都会把i对应的值存到数组里面;
(function (j) {
arr[j]=function () {
document.write(j+' ');
}
}(i))
}
return arr;
}
var arrs=bibaojiejue();
for(var j=0;j<arrs.length;j++){
arrs[j](); //打印0-9
}
闭包会导致原有的作用域链不被释放,造成内存泄漏
(作用域链不释放,内存占用,内存占用的越多,内存就越小,就像内存泄漏了一样)
function a() {
function b() {
var bb = 123;
console.log(aa);
}
var aa = 123;
return b;
}
var glob = 100;
var demo = a(); //demo = b();
demo(); //执行 b;
* a执行产生两个 一个go{};一个ao{};
* b(被保存到了函数外部)定义时候引用的是a产生的两个go{},ao{},产生了闭包;
*a执行完,并不会销毁a的作用域,因为b还在用着;
*作用:实现共有变量,eg:函数累加器;可以做缓存(存储结构);可以实现封装,属性私有化,
模块化开发防止污染全局变量;
//累加器:
function add(){
var count = 0;
function demo(){
count ++;
console.log(count);
}
return demo;
}
var nihao=add();
nihao();
nihao();
nihao();
//缓存:
function eater() {
var food = ''; //隐式的存储结构
var obj = {
eat:function () {
console.log('我爱吃'+food);
food = '';
},
push:function (myfood) {
food = myfood;
}
}
return obj;
}
var aichi=eater();
aichi.push('pingguo');
aichi.push('juzi');
aichi.eat();
//立即执行函数(也可以有名字,参数,返回值,预编译,不过名字会被忽略,执行完就释放);
function zizhixing() { //正常函数声明,等待被执行 占用空间;
}
//针对初始化的函数,只执行一次,就用理解执行函数(执行完立即释放);
(function () {
console.log(123+456);
})();
var numss=(function (a,b) {
console.log(a+b);
return a+b;
})(1,3);
console.log(numss);
//两种写法
(function () {}()); // w3c 建议这种
(function () {})(); //
//只有表达式才能被执行符号执行
// console.log('bunnegzhixing');
// }();
var tes=function buenng() { //函数表达式 ,所以这边可以被执行;能被执行符号执行的表达式基本是立即执行函数
,那么这个函数的名字就会被忽略;
console.log('bunnegzhixing');
}()
//只要是表达式就会被()执行;加上正号,负号,&&,||,!都会使函数成为表达式;
(function test(){console.log('a')});
function nihaoss() {
var arr=[];
for(var i=0;i<10;i++){
arr[i]=function () {
document.write(i+' '); //i等于10的时候 for循环结束;
}
}
return arr;
}
var arrs=nihaoss();
console.log(arrs); //此时i=10; 闭包出来他们用的是同一个go,ao;
for(var j=0;j<arrs.length;j++){
arrs[j](); //打印10
}
function bibaojiejue() {
var arr=[];
for(var i=0;i<10;i++){ //10个立即执行函数,每次都会把i对应的值存到数组里面;
(function (j) {
arr[j]=function () {
document.write(j+' ');
}
}(i))
}
return arr;
}
var arrs=bibaojiejue();
for(var j=0;j<arrs.length;j++){
arrs[j](); //打印0-9
}
闭包会导致多个执行函数公用一个公有变量,如果不是特殊需要,应防止这种情况发生。