2

一,理解闭包就要先理解作用域

作用域scope 在js中作用域scope是由函数划分的,所有属于全局作用域的变量都是window对象的属性(prototype);

function A(){
 var num =2;
 function B(){
 console.log(num);
  }
}
//B函数可以访问A函数,A函数外不能访问A函数里定义的变量,那么B函数能访问A函数里定义的变量;
//那么可以将B函数作为返回值,然后提供给外部(作为接口),那么外部就能访问A函数里的变量了
//链式作用域chain scope :子对象一级一级向父级对象寻找变量

var num = 2;
var obj = {
   num :3,
   getNum :function (){
   console.log(this.num)
  }
}
obj.getNum();//3


var n = 2;
var obj = {
    n:3,
    getNum:function (){
    setTimeout(console.log(this.n),3000);
    }
}
obj.getNum();//3


var n = 2;
var obj = {
     n:3,
     getNum:funciton(){
     setTimeout(function(){
        console.log(this.n)
     },3000)
     }
};
obj.getNum();//2

二,闭包closure:内层的函数可以引用他外层函数内的变量,即使外层的执行已经终止

//闭包的典型案例,实现访问函数内部的变量
function people() {
 var name = "maoguotao";
 function getname(){
    console.log(name);
 } 
return getname;
}
var person = people();
person();

函数getName就是这个people函数的对外接口提供能够访问到内部定义的name,因此getName函数和变量name组成的环境就称之为闭包;

闭包的两个特点:1,可以访问函数内部的变量,2,这些变量的值始终是保存在内存中

1.可以访问函数内部的变量

function A(){
    var name = "maoguotao";
    this.getName = function () {
       console.log(name);
    }
}

var a = new A();
a.getName();

2.这些变量的值始终是保存在内存中

function A(){
 var name = "maoguotao";
 addName = function (){
     name = name + "12";
  }
 function getName(){
     console.log(name+"34");
 }
return getName;
}
var a = A();
a();
//maoguotao34
addName();
a();
//maoguotao1234

a函数执行了两次,也就是说闭包getName函数执行了两次,实际上局部变量name是保存在内存中的,并没有在第一次的a()调用完之后清除,因为A函数是getName闭包函数的父函数,而getName函数被赋给a全局变量,使得getName函数始终在内存中,而getName函数依赖于A函数,所以A函数也是在内存中,不会在调用结束后清除;

闭包的缺点:
1,闭包使得函数中的变量保存在内存中,对内存消耗很大,不能滥用,会造成网页的性能问题,在IE中可能导致内存的泄露,解决办法就是在退出函数之前将使用的局部变量全部删除;

2,闭包会在父函数外部,改变父函数的内部变量的值,因此,把父函数当作Object对象使用,把闭包当作他的公用方法,把内部变量当作他的私有属性;


MGT360124
5 声望0 粉丝

前端开发