一、立即执行函数
IIFE - immediately invoked function expression
自动执行,执行完成以后立即释放。
常用于初始化函数。
普通的函数在全局定义之后是存在GO中的,是不释放的,在想调用的时候就能调用 有些函数只需要运
行一次之后再也不会执行 -> 立即执行函数
就是执行之后GO中就没有了
写法
(function(){})();(function(){}()); //w3c建议
传参
// 形参;(function(a, b) {console.log(a + b); // 3})(1, 2); // 实参
返回值
var sum = (function(a, b) {return a + b;})(5, 6);console.log(sum); // 11
错误写法
var f= (function(a,b){console.log(a+b)}(2,5))f()
代码例子
var test=function(){console.log(1)}();test();
立即运行1,没有分号;也行但最好写,不写很有可能报错,两边都写也行,实在不行里边都写
写test() 提示test is not a function
console.log(1)function test3(){console.log(1);}();
显示Uncaught SyntaxError: Unexpected token ‘)’ 这是语法错误,不会打印1
只有表达式才能被执行符号()执行
var test1=function(){console.log(2) //直接运行}();console.log(test1) //undefined// var test1 = function a() { //一样// console.log(2)// }();// console.log(test1) //undefined
2 undefined 运行完立即销毁,所以是undefined,并不是赋值不了
(function(){console.log(123)})();(function test(){console.log(123)})();
当运行完立即销毁,所以加不加函数名是一样的
var a = function () {console.log('a')}()var b = (function () {console.log('b')})
表达式
概念
(1+2)*3;1;(1);
被()括起来的都是表达式,1也是表达式,括号括起来的都是表达式,都会变成表达式。
一定是表达式才能被执行符号执行。
括号括起来的都是表达式。
表达式会忽略函数的名称。
函数声明变成表达式的方法:
+、-、!、||、&&、,、void
+function test1() {console.log(1);}();+function(a, b) {console.log(a+b)}(1,5)-function test2() {console.log(2);}();!function test3() {console.log(3);}();true && function test4() {console.log(4);}();false || function test5() {console.log(5);}();void function test6() {console.log(6);}();2, 3, function test7() {console.log(7);}();
题目
function test(a,b){console.log(1)}(6);/*这是对的,代码解析成*/function test(a,b){console.log(1)};(6);/*认为(6)是表达式*/function test(a){}();/*Uncaught SyntaxError: Unexpected token ')'错的,不写不会认为是表达式,不会认为()是表达式*/
var num=(2-1,6+5,24+1);console.log(num);//25
闭包深入
题目1
function test() {var arr = [];for (var i = 0; i < 10; i++) {arr[i] = function () {document.write(i + " ");};}return arr;}var arr = test();for (var j = 0; j < 10; j++) {arr[j](); // 10个10}
题目1分析
循环可以变成
function test() {var arr = [];var i=0;for (; i < 10; ) {arr[i] = function () {document.write(i + " ");// console.log(i);//10个10};i++;}return arr;}var arr = test();for (var j = 0; j < 10; j++) {arr[j](); // 10个10}
闭包,因为arr[]数组中存着func函数,function () {document.write(i + “ “);}; 而i的值并没有确定下来,当运行完时i的值为10确定下来不再改变,所有的函数指向i最终的值10
解决方法1
function test() {var arr = [];for (var i = 0; i < 10; i++) {arr[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 arr = test();for (var j = 0; j < 10; j++) {arr[j](j); // 1,2...9}
解决方法3
function test() {var arr = [];for (var i = 0; i < 10; i++) {(function (j) {arr[j] = function () {document.write(j + " ");};})(i);}return arr;}var arr = test();for (var j = 0; j < 10; j++) {arr[j](); // 0-9}
结果1 2…9
把j换成i也一样
代码题目
<body><ul><li>0</li><li>1</li><li>2</li><li>3</li><li>4</li></ul><script type=text/javascript>var oLi = document.querySelectorAll('li');var oLength = oLi.length;// for (var i = 0; i < oLength; i++) {// oLi[i].onclick = function() {// console.log(i);// }// }for (var i = 0; i< oLength; i++) {(function (j) {oLi[j].onclick = function() {console.log(j);}})(i)}</script></body>
逗号运算符
expr1,expr2,…
对它的每个操作数求值(从左到右),并返回最后一个操作数的值。
console.log((1, 5, 8)); // 8var fn = (function test1() {return 1;},function test2() {return '2';})();console.log(typeof(fn)); // 'string'
fn是’2’, typeof返回的是字符串
面试题目
var a = 10;if (function b(){}) { //()表达式,忽略函数名a += typeof(b);}console.log(a); // '10undefined'
作业
闭包实现累加器
function sum() {var n = 0;function add() {n++;console.log(n);}return add;}var add = sum();add();add();add();add();
function sum(){var n = 0;function add(){n++;return n;// console.log(n)}function reduce(){n--;return n;// console.log(n)}return [add,reduce]}var ys=sum();// ys[0]()// ys[0]()// console.log(sum()[0]())// console.log(sum()[0]())console.log( ys[0]())console.log(ys[0]())
return也行,但没有函数保存写sum()[0]不行,必须外部变量保存,从而不让其销毁
闭包写法,1返回函数,2外部变量接收
function fnx2() {var num = 0;function add() {num++;console.log(num);}function sub() {num--;console.log(num);}// var optarr = [// function add() {// num++;// console.log(num);// },// function sub() {// num--;// console.log(num);// }// ]return {add,sub};}// var arr2 = fnx2();// arr2[0](10);// arr2[1](10);var arr2=fnx2()console.log(arr2);arr2.add()//1arr2.add()//2
一个班级:学生名字保存在一个数组里;
两个方法写在函数中的一个对象中;
第一个方法加入班级;
第二个方法离开班级;
每次加入或离开,都需要打印新的学生名单
function student() {var students = ['张三', '李四', '王五'];var fn = {join: function (name) {students.push(name);console.log(students);},leave: function (name) {var idx = students.indexOf(name);students.splice(idx, 1);console.log(students);}}return fn;}var fn = student();fn.join('小明');fn.join('小红');fn.leave('张三');
<script>var x=1,y=(z=0);y=add(x);function add(n){n=n+3;return n;return n=n+3;}z=add(x);console.log(x,y,z)/*AO={n->undefined->1->n=n+3=4}因为n是参数,函数运行时产生AO,n才初始化为undefined,把x的值1赋值给n,n=1,之后n=n+3等于4,函数运行完AO销毁,n就销毁了,之后再运行继续n的初始化,继续上述流程*/</script>
