匿名函数具名化【官方推荐规范】

  • 应该是匿名函数的
  • 自执行函数
  • 函数表达式
  • 回调函数 setTimeout(function(){},1000)

匿名函数具名化特点

1.设置的名字,并不会在所处上下文中进行声明

  1. (function A() {
  2. // ...
  3. })();
  4. console.log(A); //Uncaught ReferenceError: A is not defined

2.在函数执行形成的私有上下文中,会把这个名字作为一个私有变量「存储到AO中」,变量值是当前函数本身「堆内存地址」; 并且默认情况下,对这个变量值进行修改是无效的;

  1. (function A() {
  2. A = 100; //无效操作
  3. console.log(A); //函数本身
  4. })();

3.但凡函数内部,这个名字被我们手动的声明过「例如:形参/var/function/let/const…」,都认为这个名字是我们自己玩的私有变量,和默认值是当前函数本身没关系了!! “默认是函数本身的这个点,权重太低”

  1. /*
  2. * EC(AA)
  3. * A--------->函数本身
  4. * 作用域链
  5. * 形参赋值--
  6. * 变量提升:var A
  7. */
  8. (function A() {
  9. console.log(A); //undefined
  10. var A = 100;
  11. console.log(A); //100
  12. })();
  13. /*
  14. * EC(AA)
  15. * A--------->函数本身
  16. * 作用域链
  17. * 形参赋值 A ===100
  18. * 变量提升:---
  19. */
  20. (function A(A) {
  21. console.log(A); //100
  22. A = 200;
  23. console.log(A); //200
  24. })(100);
  25. (function A(A) {
  26. console.log(A); //100
  27. function A(){}
  28. console.log(A); //200
  29. })(100);
  30. /*
  31. /!*
  32. * EC(G)
  33. * b --> 10
  34. *
  35. * 变量提升: var b;
  36. *!/
  37. var b = 10;
  38. (function b() {
  39. /!*
  40. * EC(B) 私有上下文
  41. * b --> 当前函数本身
  42. * 作用域链:<EC(B),EC(G)>
  43. * 形参赋值:--
  44. * 变量提升:--
  45. *!/
  46. b = 20; //无效操作
  47. console.log(b); //当前函数本身
  48. })();
  49. console.log(b); //10

匿名函数具名化作用:

因为我们可以在函数内部,基于这个名字访问到这个函数,这样就可以实现一些原本不具备的能力,例如:递归

“use strict”; 开启JS严格模式「语法要更加严谨,目前我们开发,基于webpack打包后,都是严格模式」

  1. "use strict";
  2. (function () {
  3. // 递归?
  4. // arguments.callee:代表当前函数本身
  5. // arguments.callee.caller:存储函数在哪执行的
  6. // 但是在严格模式下,都嗝屁了,不允许使用....
  7. console.log(arguments);
  8. })();
  9. (function A() {
  10. // 实现递归处理
  11. // console.log(A); //函数本身
  12. A();
  13. })(); //死递归 内存溢出

了解arguments.callee 和arguments.callee.caller

  • arguments.callee:指的是函数本身
  • arguments.callee.caller 指的是函数执行的宿主环境,如果是在函数A中执行,打印出来的就是A,如果是在全局作用域中执行,打印出来的就是null。
  1. function fn(){
  2. console.log(arguments.callee); // 打印出的是fn 函数本身
  3. }
  4. fn();
  5. function fn(){
  6. console.log(arguments.callee.caller);
  7. }
  8. fn(); // 此时打印出的是 null(在全局作用域中执行)
  9. function fn(){
  10. console.log(arguments.callee.caller);
  11. }
  12. function A(){
  13. fn(); // 此时打印出的是 A这个函数
  14. }
  15. A();