函数声明(创建):

创建函数的几种方式

1. 声明函数

  1. function fn1(){}

2.创建匿名函数表达式(推荐)

创建一个变量,这个变量的内容为一个函数
这种方式,可防止函数的变量提升,造成干扰。

  1. var fn1 = function(){}

3.创建具名函数表达式

创建一个变量,内容为一个带有名称的函数
注意:

  • 这个函数名只能在创建函数内部使用;不能在外部访问,即:不会在当前上下文中创建这个名字
  • 函数执行时,在函数内部,会把这个函数名(具名)作为私有上下文的变量来处理,进而可以在函数内部直接递归调用,而不必使用 arguments.callee()了 ```javascript var fn1 = function AAA(){ console.log(AAA); AAA(); // 递归调用 };

AAA(); // 报错:Uncaught ReferenceError: AAA is not defined fn1(); // ƒ AAA(){…}

  1. <a name="YLgRA"></a>
  2. #### 4.Function构造函数
  3. <a name="sMD2U"></a>
  4. ### 创建和执行的过程
  5. <a name="UNyiC"></a>
  6. #### 创建函数:
  7. 在某个上下文中创建函数,会开辟内存和赋值
  8. - 创建一个堆(存储`代码字符串`和`对应的键值对`)
  9. - **函数也是对象**,也有自己的键值对,如`prototype`、`length`、`name`
  10. - 初始化了当前函数的`作用域`
  11. - `[[scope]]` = **当前函数创建时所在的上下文中的的变量对象`VO/AO` **
  12. 故JS函数使用的是**词法作用域:**函数的上下文在创建时,就已经确立好了;函数在哪个上下文创建的,它的作用域就是谁。<br />而不是使用**动态作用域**。
  13. ```javascript
  14. var scope = "global scope";
  15. function checkscope(){
  16. var scope = "local scope";
  17. function f(){ console.log(scope); }
  18. return f();
  19. }
  20. checkscope(); // "local scope"
  21. -------------------------------------------
  22. var scope = "global scope";
  23. function checkscope(){
  24. var scope = "local scope";
  25. function f(){ console.log(scope); }
  26. return f;
  27. }
  28. checkscope()(); // "local scope"

执行函数:

函数执行,首先都会:

  1. 创建一个新的执行上下文EC,推入到栈中;
  2. 初始化作用域链[[ScopeChain]] : <自己所在的上下文,函数作用域>,如:<EC(Fn), EC(G)>
  3. 初始化THIS的指向
  4. 创建AO对象用于存储变量
  5. 初始化实参集合:arguments,进而完成形参赋值
  6. 变量提升
  7. 代码执行
  8. 出栈 ? 取决于其是否有私有变量被其他上下文调用;