堆栈内存及闭包
JS中的堆栈
let a = 0;
let b = a;
b++;
aleart(a) // "0"
let o = {};
o.a = 0;
let b = o;
b.a = 10;
aleart(o.a) // "10"
aleart()输出的结果都是字符串,toString()
JS中的数据类型:
- 基本类型(值类型):number string boolean null undefined
- 引用类型:object function
- 特殊类型:symbol
-
栈内存:提供代码运行的环境,存储基本类型
全局作用域 =》执行上下文栈
等号赋值:1. 创建变量 2. 创建值 3.关联
变量和值的关联是指针指向
栈内存 存a和b这两个变量和0这个值,ab都指向0这个值。b=b+1,b=1,此时b关联1,不再和0关联,但是a还和0关联,所以a=0; -
堆内存:提供引用类型存储的空间
堆中存a: 0,o和b都指向堆内存中变量a的地址(16进制),a改变,b.a = 10,堆内存中的a变为10,因此o.a=10
let a = {
n: 1,
}
let b = a;
a.x = a = {
n: 2,
}
console.log(a.x); // undefined
console.log(b); // { n: 1, x: { n: 2 } }
a.x = a =,按顺序 先a.x = {…},再a={…}
- GO:全局对象
- EC(G):全局执行上下文,压入ECstac(进栈),执行全局代码
- ECstac:执行上下文栈 =》栈内存
- EC:执行环境(执行上下文)
- AO:活动对象(函数的叫做AO,相当于VO的分支)
- VO:变量对象
- scope:作用域,⚠️所有的在当前的执行上下文当中,只要创建了函数,必然会给函数增加[scope]属性 =》 所以函数作用域是在函数创建的时候形成的
- scope Chain:作用域链
函数每次执行的时候都会创建一个全新的执行上下文
let x = 1;
function A(y) {
let x = 2;
function B(z){
console.log(x + y + z);
}
return B;
}
let C = A(2);
C(3);
eg:
let a = 12, b = 12;
function fn(){
let a =b =13;
// let a = 13; 这个a是私有的
// b = 13; 这个b不是私有的,是上级作用域的b,因此上级作用域的b由12变成13
console.log(a, b);
}
fn();
console.log(a, b);
// 答案: 13 13 12 13
eg:
当前作用域的操作可能会把上级作用域中的变量改变拿来使用,此时上级作用域的变量被占用,此上下文不能被销毁,就形成了闭包。形成不能被销毁的执行上下文=》闭包
老师的一句话说的很好:学东西,要知其然而知其所以然!!!
b站课程笔记,视频链接:https://www.bilibili.com/video/BV1oz411t78i?from=search&seid=10784965498570581667