js——闭包问题

js——闭包问题

一、理解闭包

首先根据下面的例子来理解闭包的概念:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var ourVar = 'liming'
var later;

function outerTest(){
var inner = 'haha';
function innerTest(){
console.log(inner);
console.log(ourVar)
}
later = innerTest;
}

outerTest();
later();
//运行的结果是:
//haha
//liming

在上面的代码中,在外部函数我们声名了一个变量inner,然后又声名了一个内部函数innerTest,接下来在内部函数中访问全局变量ourVar和函数内的变量inne,之后为了在全局中能够调用这个内部函数,在全局变量中设置了一个变量接受这个函数,通过调用outerTest创建内部函数并将内部函数赋给later,之后调用later。可以看见,即使现在内部作用域消失在执行内部函数时,内部变量依然存在。

这是因为在外部函数声明内部函数的时候,不仅定义了函数的声明,而且创建了一个闭包。闭包不仅包含了函数的声明,还包括了在函数声明时该作用域的全部变量。在执行内部函数的时候,虽然作用域已经消失,但是通过闭包,还能访问原始的作用域。

二、使用闭包

1.封装私有变量

虽然JavaScript不支持私有变量,但我们可以利用闭包的特性来实现私有变量的基本功能。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function student(){
var age = 23;
this.name = "liHua"
this.getAge = function(){
return age;
}
this.increase = function(){
age++;
}
}

var stu1 = new student();
console.log(stu1.age)
console.log(stu1.name)
console.log(stu1.getAge())
//运行结果
//undefined
//liHua
//23

上述代码中,我们定义了一个age作为student类中的私有属性。由于js的作用域规则的限制,只能在构造器内部访问该变量。所以直接访问stu1.age执行的结果就是undefined。为了让外界可以接触这个变量,可以利用getAge来向外暴露。虽然这时候,函数的作用域结束了,但实例化对象通过this拥有这个作用域,所以可以访问他的方法。注意这里直接var定义的属性和利用this定义的属性是不一样的。

0%