1.立即执行函数
IIFE => immediately invoked function expression
写法2: w3c推荐写法 (function(){ }())
<a name="YhNDf"></a>### ()包起来的,都是表达式,一定是表达式才能被执行```javascript(function(){console.log(可以立即执行);})()function(){}()=> 理解成function(){}() 并不会立即执行// 可以被执行,var test = function(){console.log(2);}()console.log(test); // undefined
1.2 可以携带参数
(function(a, b){console.log(a + b); // 6})(2, 4)
1.3 立即执行函数的返回值
var test = (function(a, b){return a + b})(2, 3)console.log(test); // 5var name = (function(name){return name})('bobo')console.log(name); // bobo
1.4 函数可以立即执行的情况
1. 第一种(function(){console.log(1);})()2. 第二种var test = fucntion(){console.log(1);}() // 可以执行,因为()之前为表达式3.第三种function test(){console.log(1);}() // 会报错!() 内部不写, 会报错function test(){}('1') 传入会被当表达式,不会报错,不会执行
1.5 立即执行函数立即执行结束后,就会被销毁
var test = (function(){console.log(1); // 1})()console.log(test);// undefined// 打印 1 和 undefined 证明立即执行函数执行结束之后,立即被销毁了,// 所以test是undefined
1.6 立即执行函数的函数名无意义,会自动被忽略,
var a = 10;if(function b(){}){a += typeof(b);}console.log(a); // '10undefined'
1.7 把函数声明变成表达式的方法 + - ! || && void
+function(){console.log(1);}() // 1-function(){console.log(1);}() // 1!function(){console.log(1);}() // 10 || function(){ // 隐式转换成fasle的都可以 undefined null false 0 ''console.log(1);}() // 11 && function(){ //隐式转换不是false的都可以console.log(1);}() // 1void function(){console.log(1);}() // 12, 3, function(){console.log(1);}() // 1
2. ,逗号运算符
对它的每个操做数求值,从左到右,返回最后的值。
var num = (2, 3, 45, 767);console.log(num);// 767
3.闭包深入
案例1: 打印0-9
function test() {var arr = [];for(var i = 0; i < 10; i++) {arr[i] = function() {document.write(i + '');}}return arr;}var myArr = test();for(var j = 0; j < 10; j++) {myArr[j]();} // 打印10个10// 方法1 => 立即执行函数function test() {for(var i = 0; i < 10; i++) {(function() {document.write(i + '');})()}}test();// 方法2 在外边传入参数function test() {var arr = [];for(var i = 0; i < 10; i++) {arr[i] = function(num) {document.write(num + '');}}return arr;}var myArr = test();for(var j = 0; j < 10; j++) {myArr[j](j);}// 方法3 将其在函数内部进行保存function test() {var arr = [];for(var i = 0; i < 10; i++) {(function(j){arr[j] = function(j){document.write(j + ' ');}})(i)}return arr;}var myArr = test();for(var j = 0; j < 10; j++) {myArr[j]();}
案例2: 点击事件打印
<ul><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li></ul><script type="text/javascript">var oLi = document.querySelectorAll('li');console.log(oLi);for(var i = 0; i < oLi.length; i++){(function(j){oLi[j].onclick = function(){console.log(j);}})(i)}</script>
4.面试
function test(a){console.log(a);// 不会执行}(6) // (6) 被当成了表达式,而不是立即执行符号test(1);// 打印输出 1
var fn = (function test1(){return 1},function test2(){return '2'})();console.log(fn);// '2'console.log(typeof(fn));// string
var a = 10;// ! (function b(){}) => 表达式,函数名称被忽略, => undefinedif(function b(){}){a += typeof(b);}console.log(a); // 10undefined
5.练习
1. 累加器,初始值为0,写个闭包,执行一次函数加1打印
function accu(){var i = 0;return function add(){// i++;// console.log(i);console.log(++i);}}var accu1 = accu();accu1();accu1();accu1();
2. 缓存器:
缓存器 : 一个班级,学生名保存在一个数组,俩个方法写在函数中的一个对象中,
第一个方法,加入班级,第二个方法离开班级
每次加入或离开,都需要打印新的学生名单
function buffer(){var studentsArr = ['小明','小红'];var operStd = {join:function(name){studentsArr.push(name);console.log(studentsArr);// for(var i = 0; i < studentsArr.length; i++){// (function(){// console.log(studentsArr[i]);// })()// }},quit: function(name){var index = studentsArr.indexOf(name);// console.log(index);if(index !== -1){studentsArr.splice(index,1);}console.log(studentsArr);// for(var i = 0; i < studentsArr.length; i++){// var item = studentsArr[i]; // ? for循环型性能 的优化// if(item === name){// studentsArr.splice(i);// }// }}};return operStd}var operStd = buffer();operStd.join('小阿飞');operStd.quit('小红');

