作用域、作用域链、立即执行函数、闭包
闭包的作用:
1、实现公有变量
eg:函数累加器
2、可以做缓存(存储结构)
eg:eater
3、可以实现封装,属性私有化
eg:Person();
4、模块化开发,防止污染全局变量
立即执行函数
//立即执行函数
//针对初始化功能的函数
//执行完之后就会被销毁,只能执行一次
1 var num = (function(a,b,c){ 2 var d = a+b+c*2 -2;4 return d;5 }(1,2,3))
//只有表达式才能被执行符号执行,
//函数被括号包裹就变成了表达式
//函数声明不能被执行
可以用+ 、-将其转化为表达式
1 + function test(){ 2 console.log(); 3 }(); 4 - function test(){ 5 console.log(); 6 }();
arguments
arguments是类数组对象,不能使用push方法;
1、实现公有变量
累加器
function add(){ var num = 0; function a(){ console.log(++num); } return a; } var myAdd = add(); myAdd(); myAdd();
function add(){ var count = 0; function demo(){ count++; console.log(count); } return demo; } var counter = add(); counter();//没调用一次累加一次 counter(); counter(); counter();
解决闭包问题的方法:用立即执行函数
遍历元素加上事件,最好在循环中用立即执行函数,避免闭包问题;
arguments[0]和第一位参数之间的关系:同形连体,一个改变,另一个也随之改变,但不是同一个人;
2、可以做缓存(存储结构)
function test() { var num = 100; function a() { num++; console.log(num); } function b() { num--; console.log(num); } return [a,b]; } var myArr = test(); myArr[0](); myArr[1](); /* a 运行后的 testAO, 与 a doing 里面的 testAO 一模一样 a 和 b 连线的都是 test 环境,对应的一个闭包 function a 和 function b 是并列的,不过因为 function a 在前,所以先执行 num ++,在 执行 num -- myArr[0]是数组第一位的意思,即 a,myArr[0]();就是执行函数 a 的意思; myArr[1]是数组第二位的意思,即 b,myArr[1](); 就是执行函数 b 的意思 */
3、可以实现封装,属性私有化
// 闭包的私有化变量问题 function Deng(name,wife) { var prepareWife = "xiaozhang";//私有只有自己可以访问 this.name = name; this.wife = wife; this.divorce = function (){ this.wife = prepareWife;//私有变量不用加this访问 } this.changePrepareWife = function(target){ prepareWife = target; } this.sayPraprewife = function(){ console.log(prepareWife); } } var deng = new Deng('deng','xiaoliu');
4、模块化开发,防止污染全局变量
var name = 'bcd'; var init = (function(){ var name = 'abc';//这个name和外面的name不冲突 function callName(){ console.log(name); } return function(){ callName(); //这个函数在外面使用时,自带上下文,不污染全局变量 } }()) init();