function f1() {
var b = 999; //999是局部变量,在函数作用域生效
function f2() {
/*
f2是闭包,能够读取其他函数内部变量的函数,可以简单理解为:闭包是定义在一个函数内部的函数。
闭包可以将函数内部和函数外部连接起来。
闭包用处:1. 读取外层函数的内部的变量
2. 让变量始终保存在内存中
*/
console.log(b); //链式作用域结构,可读取父级的变量
}
return f2;
}
f1(); //返回的是一个函数
var re = f1(); //将返回的f2函数赋给re
re(); //执行re函数
function createIncrementor(start) { //创建一个带了start参数的createIncrementor函数,当调用这个函数,可传入start参数。传入的参数作用体现在:函数的结果会随着start参数变化而变化
return function () { //createIncrementor返回一个匿名函数
return start++; //匿名函数返回createIncrementor传入的start++,这里可以留意下start++和++start区别,start++是执行之后再加1,++start是先加1后再执行
}
}
var re = createIncrementor(6);//调用createIncrementor函数,这里会返回一个匿名函数,可将匿名函数赋值给一个变量re。这个时候re指向了createIncrementor中的匿名函数,即闭包,该闭包可以使用父级的局部变量
re(); //调用re函数,返回父级参数start++,即6
re(); //再次调用re函数,会再次返回父级参数start++,即7. 闭包用到了外层变量start,导致外层函数不能从内存释放,只要闭包没有被垃圾回收机制清楚,外层函数提供的运行环境也不会被清除,它的内部变量会始终保存着当前值,供闭包读取
function Person(name) { //定义一个带name参数的person函数
var _age; //定义person函数中的属性,属性名字叫做_age
function setAge(n) { //(闭包:封装对象的私有属性和私有方法)定义person函数中的方法,用来设定person的年龄,方法名字叫做setAge,传入需要设定的年龄参数:n
_age = n; //将setAge传入的参数n,赋值给person函数的_age属性
}
function getAge() { //(闭包:封装对象的私有方法)定义person函数中的方法,用户获取person的年龄,方法名字叫做getAge。由于是获取person的年龄,不需要传入参数,只需要传入person的name参数即可,所以getAge的方法不需要传参
return _age; //getAge方法返回person的_age属性
}
return { //person函数返回一个对象,对象包含传入的name参数、getAge方法,setAge方法
name: name,
getAge: getAge,
setAge: setAge
};
}
var p1 = Person("张三"); //执行Person函数,根据Person函数定义,返回一个对象,将对象赋值给p1变量
console.log(p1);
//p1对象包含对象属性和方法,可供后续使用
console.log(p1.name); //比如打印p1对象的name属性
p1.setAge(15); //调用p1对象的setAge方法,setAge方法根据上述的定义,需要传入参数
p1.getAge(); //调用p1对象的getAge方法,getAge方法获取p1对象的年龄,无需传参