📌 立即执行函数IIFE(immediately invoked function expression)

立即执行函数 创建后立即执行,本质是函数表达式

  • 页面加载自动执行,执行完成立即销毁(故忽略函数名) ```javascript //第一种写法——————————— (function(){ … })();

//第二种写法【W3C建议写法】——————————- (function(){ … }());

  1. **函数**只要**以表达式形式**出现,无论**有名与否**,无论**执行与否**,其**自动忽略函数名**,通过函数名**调用会报错**,typeof检测**类型为undefined **
  2. > **注意:错误写法——报语法错误**
  3. > ** Uncaught SyntaxError: Unexpected token ")" **
  4. ```javascript
  5. //错误的写法
  6. function (){
  7. ...
  8. }();    //报错: Uncaught SyntaxError: Unexpected token (
  • 错误原因
    • 一定是表达式才能被执行符号执行
      • 语句后的()会被当做分组操作符,分组操作符里不能未空必须有表达式,所以报错
      • 即使()内有值或表达式,JavaScript引擎会将其当作单独的表达式来解析,不报错,函数因未被调用而不会执行
    • 因其执行完成立即销毁,所以立即执行函数忽略函数名(在其外部使用函数名调用报错未定义)
      1. //让Javascript引擎认为这是一个表达式的方法还有很多
      2. !function(){}();
      3. +function(){}();
      4. -function(){}();
      5. ~function(){}();
      6. 0 || function(){}();
      7. 1 && function(){}();
      8. new function(){ /* code */ }
      9. new function(){ /* code */ }() // 只有传递参数时,才需要最后那个圆括号

经典实用场景案例 利用立即执行函数弹出对应事件索引

  1. <!DOCTYPE html>
  2. <html lang="zh-CN">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>利用立即执行函数弹出对应事件索引</title>
  7. </head>
  8. <body>
  9. <ul>
  10. <li>点击,打印0</li>
  11. <li>点击,打印1</li>
  12. <li>点击,打印2</li>
  13. <li>点击,打印3</li>
  14. <li>点击,打印4</li>
  15. </ul>
  16. <script>
  17. var lis = document.querySelectorAll("li")
  18. for (var i = 0; i < lis.length; i++) {
  19. (function (j) {
  20. lis[j].addEventListener('click', function () {
  21. console.log(j);
  22. })
  23. }(i))
  24. }
  25. </script>
  26. </body>
  27. </html>

立即执行函数 和 闭包 的区别 ? 两者经常会结合在一起使用,但其两者本质不同

  • **共同点**:
    • 可以减少全局变量的使用
  • 不同点**:**
    • 立即执行函数:声明之后立即执行,一般只调用一次后立即销毁,不占内存空间
    • 闭包:让外部可以访问其内部作用域,保证内部变量安全,但其内部变量被引用无法销毁,增加了内存消耗,可能造成内存泄漏

📌 逗号运算符

逗号运算符 执行所有的操作数,只返回最后一个操作数的值 逗号运算符在JavaScript中的优先级是最低的

  • 单一var声明模式,多个变量连续赋值 ```javascript var a = 1,b = 2,c = 3,d = 4;

// 等价于———————————————— var a = 1; var b = 2; var c = 3; var d = 4;

  1. - **逗号运算符可用于赋值,返回表达式中的最后一项**
  2. ```javascript
  3. var num = (1,2,3,4,5);
  4. console.log(num); // 5
  • 常用于for循环中,可循环多个变量
    1. for(var i= 0,j = 10; i < j; i++, j--){
    2. console.log(i + j) // 10 10 10 10 10
    3. };

📋 课后作业

1、累加器,初始值0,利用闭包,执行闭包函数,每执行一次+1 2、缓存器,利用闭包,学生名保存在数组里,两个方法写在函数的对象中, 方法一功能加入班级,方法二功能离开班级,每次加入或离开都需答应班级人员新名单

  1. // 累加器,初始值0,利用闭包,执行闭包函数,每执行一次+1
  2. function accumulation() {
  3. var init = 0;
  4. return function () {
  5. init++
  6. console.log(init);
  7. }
  8. }
  9. var add = accumulation()
  10. add(); //1
  11. add(); //2
  12. add(); //3
  13. add(); //4
  14. add(); //5
  15. -------------------------------------------------------------
  16. /*
  17. *缓存器,利用闭包,学生名保存在数组里,两个方法写在函数的对象中
  18. *功能方法一加入班级,
  19. *功能方法二离开班级,
  20. *每次加入或离开都需打印班级人员新名单
  21. */
  22. function cache() {
  23. var students = [];
  24. function add(newName) {
  25. students.push(newName)
  26. console.log('欢迎' + '【' + newName + '】' + '同学加入!' + '目前班级人员名单如下:');
  27. for (var i = 0; i < students.length; i++) {
  28. console.log(students[i]);
  29. }
  30. }
  31. function leave(oldName) {
  32. var idx = students.indexOf(oldName)
  33. if (idx == -1) return console.log('----查无此人----');
  34. students.splice(idx, 1)
  35. console.log('送别' + '【' + oldName + '】' + '同学!' + '目前班级人员名单如下:');
  36. if (students.length <= 0) return console.log('班级人数已经清0,目前已无人员信息');
  37. for (var j = 0; j < students.length; j++) {
  38. console.log(students[j]);
  39. }
  40. }
  41. return { add, leave }
  42. }
  43. var res = cache()
  44. res.add('张三') //欢迎【张三】同学加入!目前班级人员名单如下:张三
  45. res.add('王五') //欢迎【王五】同学加入!目前班级人员名单如下:张三 王五
  46. res.add('李四') //欢迎【李四】同学加入!目前班级人员名单如下:张三 王五 李四
  47. res.leave('小李') //----查无此人----
  48. res.leave('张三') //送别【张三】同学!目前班级人员名单如下:王五 李四
  49. res.leave('李四') //送别【李四】同学!目前班级人员名单如下:王五
  50. res.leave('王五') //送别【王五】同学!目前班级人员名单如下:班级人数已经清0,目前已无人员信息
  51. res.leave('张三') //----查无此人----