立即执行函数
立即执行函数在执行完成后会立即释放,常用于初始化变量,通常使用IIFE。
基本写法
(function () {})();
(function () {
  // W3C建议
})();
接收返回值
const sum = (function (a, b) {
  return a + b;
})(2, 4);
console.log(sum);
括号内的任何内容都是表达式。无论是函数、变量还是方法,包裹后都成为表达式。
表达式才能被执行符号()
// 无法执行
function test(){
  console.log(1);
}();
// 可以执行
const test = function () {
  console.log(1);
}();
// 使用+号将函数转换为表达式
+function test() {
  console.log(1);
}();
// 使用运算符执行
1 && function test() {
  console.log(1);
}();
立即执行函数被销毁
const test1 = function () {
  console.log(1);
};
console.log(test1);
const test2 = (function () {
  console.log(1);
})();
console.log(test2);
函数名和表达式
函数被包裹在括号内时,函数成为表达式,表达式会自动忽略函数名。执行函数后,函数名没有实际意义。
(function test() {
  console.log(123);
})();
(function () {
  console.log(123);
})();
不写函数名,只传参
不传参时不会输出任何结果。如果不传入参数,系统会将括号视为立即执行符号,导致语法错误。但如果有值,函数被视为表达式。
function test(a) {
  console.log(1);
}
10;
function test(a) {
  console.log(1);
}
// JS引擎将函数解析为表达式
10;
逗号运算
逗号运算符返回最后一个运算的值。
const num = (2 - 1, 6 + 5, 22 + 1);
console.log(num); // 23
练习题
function createFunctions() {
  const functionsArray = [];
  for (let i = 0; i < 10; i++) {
    functionsArray[i] = function () {
      document.write(i + ' ');
    };
  }
  return functionsArray;
}
const myFunctions = createFunctions();
for (let j = 0; j < 10; j++) {
  myFunctions[j]();
}
结果为什么是 10 个 10?
function createFunctions() {
  const functionsArray = [];
  let i = 0;
  for (; i < 10; ) {
    functionsArray[i] = function () {
      document.write(i + ' ');
    };
    i++;
  }
  return functionsArray;
}
const myFunctions = createFunctions();
for (let j = 0; j < 10; j++) {
  myFunctions[j]();
  // 执行10个匿名函数
}
console.log(myFunctions);
当createFunctions返回时,i的值已经是10。执行任意一个匿名函数时,都会使用createFunctions的作用域中的i值。
// 匿名函数内查找i的值,会在createFunctions的作用域中找到i=10
function () {
  document.write(i + ' ');
}

打印 0~9
在循环中立即执行函数,使函数在循环时立即执行。
function printNumbers() {
  for (let i = 0; i < 10; i++) {
    (function () {
      document.write(i + ' ');
    })();
  }
}
printNumbers();
外界传参
function createFunctions() {
  const functionsArray = [];
  for (let i = 0; i < 10; i++) {
    functionsArray[i] = function (num) {
      document.write(num + ' ');
    };
  }
  return functionsArray;
}
const myFunctions = createFunctions();
for (let j = 0; j < 10; j++) {
  myFunctions[j](j);
}
给立即执行函数传参数(常用)
function createFunctions() {
  const functionsArray = [];
  for (let i = 0; i < 10; i++) {
    (function (j) {
      functionsArray[j] = function () {
        document.write(j + ' ');
      };
    })(i);
  }
  return functionsArray;
}
const myFunctions = createFunctions();
for (let j = 0; j < 10; j++) {
  myFunctions[j]();
}
输出下标
<body>
  <!-- 点击输出下标 -->
  <ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
    <li>5</li>
  </ul>
  <script>
    const listItems = document.querySelectorAll('li');
    for (let i = 0; i < listItems.length; i++) {
      (function (index) {
        listItems[index].onclick = function () {
          console.log(index);
        };
      })(i);
    }
  </script>
</body>
立即执行函数与逗号表达式
逗号运算符返回最后一个表达式的值。
const fn = (function test1() {
  return 1;
},
function test2() {
  return '2';
})();
console.log(typeof fn); // "function"
console.log(fn); // ƒ test2()
console.log(fn()); // "2"
被忽略的函数名
let a = 10;
// function b() {} 返回 undefined,而 undefined 是字符串
if (function b() {}) {
  // (function b() {}) 是表达式,忽略名字,所以 typeof b = undefined
  a += typeof b;
}
console.log(a); // "10undefined"