函数声明(创建):
创建函数的几种方式
1. 声明函数
function fn1(){}
2.创建匿名函数表达式(推荐)
创建一个变量,这个变量的内容为一个函数
这种方式,可防止函数的变量提升,造成干扰。
var fn1 = function(){}
△3.创建具名函数表达式
创建一个变量,内容为一个带有名称的函数
注意:
- 这个函数名只能在创建函数内部使用;不能在外部访问,即:不会在当前上下文中创建这个名字
- 函数执行时,在函数内部,会把这个函数名(具名)作为私有上下文的变量来处理,进而可以在函数内部直接递归调用,而不必使用
arguments.callee()了 ```javascript var fn1 = function AAA(){ console.log(AAA); AAA(); // 递归调用 };
AAA(); // 报错:Uncaught ReferenceError: AAA is not defined fn1(); // ƒ AAA(){…}
<a name="YLgRA"></a>#### 4.Function构造函数<a name="sMD2U"></a>### 创建和执行的过程<a name="UNyiC"></a>#### 创建函数:在某个上下文中创建函数,会开辟内存和赋值- 创建一个堆(存储`代码字符串`和`对应的键值对`)- **函数也是对象**,也有自己的键值对,如`prototype`、`length`、`name`- 初始化了当前函数的`作用域`- `[[scope]]` = **当前函数创建时所在的上下文中的的变量对象`VO/AO` **故JS函数使用的是**词法作用域:**函数的上下文在创建时,就已经确立好了;函数在哪个上下文创建的,它的作用域就是谁。<br />而不是使用**动态作用域**。```javascriptvar scope = "global scope";function checkscope(){var scope = "local scope";function f(){ console.log(scope); }return f();}checkscope(); // "local scope"-------------------------------------------var scope = "global scope";function checkscope(){var scope = "local scope";function f(){ console.log(scope); }return f;}checkscope()(); // "local scope"
执行函数:
函数执行,首先都会:
- 创建一个新的执行上下文EC,推入到栈中;
- 初始化作用域链
[[ScopeChain]]: <自己所在的上下文,函数作用域>,如:<EC(Fn), EC(G)> - 初始化
THIS的指向 - 创建
AO对象用于存储变量 - 初始化实参集合:
arguments,进而完成形参赋值 - 变量提升
- 代码执行
- 出栈 ? 取决于其是否有私有变量被其他上下文调用;
