闭包: 闭包是一种特殊的对象。它由两部分构成:函数,以及创建该函数的环境。
- 函数:需要返回的函数。
- 环境:闭包创建时在作用域中的任何局部变量组成,也就是var定义的一些变量
什么时候要用到闭包
用过js的我们都知道,js可以在内部作用域中操作外部的var属性,但是在外部是无法操作内部作用域的var属性。我们有时候需要在function方法体中,定义很多var的局部属性,和java一样,这些局部属性是供成员变量的调用,让代码更加的简单,提高可读性,那么这时我们可以使用闭包。
简单的模板
function ftn() {
// var cc = ....
// var ftn = function(){}
。。。。。。
return function() {
// 应用cc ftn 在这里面
}
}
可以看到上边的模板,可以将ftn看成是一个java中的class,在里面定义一些私有变量。这样很多很杂的东西包含在了ftn中,看起来不凌乱,提高可读性,可以说闭包是js的面向对象的应用。return返回的是function ,可以在里面做一些更加复杂的封装,也可以看成一个class 如内部类? 自己怎么理解怎么想
一个比较复杂的例子
luckily = {version: '1.0'};
luckily.stray = function() {
//在封装前的一些准备,也就是环境 条件1(闭包条件)
var name = '游客' ; //定义临时属性
var display = function () {//封装复杂逻辑的方法
if( this.name) {
alert('hello '+ this.name);
}else {
alert('hello'+name)
}
}
//开始封装
return function() { //这里就是返回的函数 条件2(闭包条件)
//在写之前,我先弄明白这个luckily.stray是用来创建对象,然后通过this来引用里面的成员变量呢
//还是通过普通的调用luckily.stray()使用闭包形式返回一个方法,然后在进行创建对象
//因为我需要涉及原型、静态属性的操作,所以我使用第二种
var temp = function (b) {this.name=b }; // 定义一个返回的方法
temp.prototype.constructor = function() {
alert('更改构造函数');
}
temp.prototype.display = display; //这里display里边有this,所以放到prototype原型中,通过new即可使用
temp.move = function() {
alert(name+" 请快点离开!");
}
return temp;
}
}(); //加() 是为了定义立即执行,让luckily.stray = return后面的方法,没有括号不然luckily.stray = function() {//在封装前的一些准备 }
luckily.ftn = luckily.stray(); //执行return的function,ftn 引用temp这个function对象。 将ftn存放到luckily这个对象中
//创建对象
var obj = new luckily.ftn('stray')
obj.constructor(); //先看看构造函数还是不是 function(b){this.name=b}?已经改变了
luckily.ftn.move();
obj.display();