函数创建「和创建变量区别不是很大 -> 函数名其实就是变量」
- 单独开辟一个堆内存「16进制地址」,函数堆内存中存储的是函数体重的“代码字符串”
- 创建函数的时候,就声明了它的作用域[scope],也就是所在的上下文环境
- 把16进制的地址存放到栈中,供变量(函数名等)关联引用
函数执行过程
- 形成以全新的、私有上下文EC(...)
- 当前私有上下文中,有一个存放本上下文内声明的变量的地方AO(...)私有变量对象 -> 这里的变量都是当前上下文的私有变量「当前上下文中声明的变量、形参变量」
- 进栈执行
- 代码执行之前还要处理很多事情
- 初始化作用域链[scope-chain]
<当前自己的上下文,上级上下文(创建函数时候形成的作用域)>
-> 当前函数的上级上下文是创建函数所在的上下文(作用域)
后期函数内代码执行,遇到一个变量,我们首先看是否为自己上下文中的私有变量(看AO中有没有),如果是私有的变量,则当前变量的操作和外界环境中的变量互不干扰(没有直接关系,如果引用类型也是间接关系);如果不是自己的私有变量,则按照作用域链,查找是否为其上级上下文中的私有变量。。。直到找到EC(G)全局上下文为止,称为“作用域链机制”
- 初始化this...
- 初始话arguments...
- 形参赋值:形参都是私有变量(放到AO中的)
如果不传递实参值,默认值是undefined
...
- 变量提升...
- 代码自上而下执行...
- 一般情况下,函数执行所形成的的上下文,进栈执行完后,会默认出栈释放掉「私有上下文中存储的私有变量和一些值都会释放掉」
-> 目的:为了优化内存空间,减少栈内存的消耗,提高页面或者计算机的处理速度...
题
1.
var x = [12, 23]
function fn(y) {
y[0] = 100
y = [100]
y[1] = 200
console.log(y)
}
fn(x)
console.log(x)
2.
var x = [12, 23]
(function fn(y) {
y[0] = 100
y = 100
y[1] = 200
console.log(y)
})(x)
console.log(x)
/*
100
[100, 23]
*/