文 / 景朝霞
来源公号 / 朝霞的光影笔记
ID / zhaoxiajingjing
图 / 自己画
❥❥❥❥点个赞,让我知道你来过~❥❥❥❥
【前情提要】
【iview】
0 / 举个例子
var a = 10;
var obj = {
id:'zhaoxiajingjing',
name:'公号:朝霞的光影笔记'
};
function func(a) {
console.log(a);
}
func(1);
△图13.1:代码的图解
内存分为:栈内存(stack),堆内存(heap);以谷歌的webkit为例,要清楚我们自己在打开浏览器时产生的堆栈内存:
(1)在浏览器中打开页面,浏览器引擎会渲染相关的代码(包括JS代码),把代码自上而下执行
(2)浏览器想要执行代码,会提供一个供代码执行的环境:Execution Context Stack(执行环境栈ECStack)栈内存
(3)最开始执行的是全局代码,所以会形成一个Execution Context(Global)全局执行上下文(EC(G)),在栈内存中执行全局代码
(4)在全局的执行上下文中有一个Variable Object (Global) 全局变量对象(VO(G)是有浏览器底层语言写的),可以把需要定义的变量和对应的值存储在这里
(5)var a =10;
① 创建一个值10(基本数据类型直接存储在栈内存中)
② 创建一个变量a(把其直接存储在VO(G)中)
③ 让创建的变量a和值10关联在一起(赋值操作)
(6)let obj = {id:'zhaoxiajingjing', name:'公号:朝霞的光影笔记'};
① 创建值:
1)开辟一个堆内存(heap),每一个堆内存都有一个16进制的地址2)把对象中的键值对分别存储在堆内存中
3)把堆内存的地址存放在栈内存中,供变量的引用
②创建一个变量
③让变量和之前创建的堆内存地址进行关联
(7)function func(a){....}
①创建值:
1)开辟一个堆内存(heap),每一个堆内存都有一个16进制的地址2)把函数体中的代码以字符串的格式存入到堆内存中
3)把堆内存地址存放在栈内存中,供变量的引用
②创建一个变量(函数名也是变量名)
③让变量和之前创建的堆内存地址进行关联
(8)func(1);
函数执行
①创建一个全新执行上下文,浏览器开辟一块栈内存EC(func),并且压入执行环境栈中,才能执行
②初始化THIS
③初始化作用域链
④在当前执行上下文中有一个Activation Object 活动对象(AO(函数)是有浏览器底层语言写的),可以把:形参赋值、定义的变量和值存储在这里
⑤代码执行
函数执行就会形成栈内存(从内存中分配一块空间),如果内存都不销毁释放,很容易导致内存溢出(爆满,卡死了)。
数据类型:基本数据类型值和引用类型值
基本类型值:结构相对简单,直接把创建的值存储到栈内存即可
string、boolean、number、undefined、null、symbol
引用数据类型值:结构相对复杂(一个综合体,包含很多值),不能直接存储在栈内存中,需要单独开辟空间来存储,这个空间就是堆内存
(1)对象数据类型 object普通对象{}、数组对象[]、正则对象/^$/、日期对象 new Date、数学函数对象 Math
(2)函数数据类型 function
1 / 栈内存释放
栈内存的两个作用:
1、提供代码执行的环境
2、存储基本类型值
打开浏览器形成的全局作用域是栈内存
函数执行形成的私有作用域是栈内存
基于ES6的let/const形成的块级作用域是栈内存
....
那么,栈内存释放:
1、全局栈内存:关闭浏览器
2、私有栈内存:
(1)一般情况下,函数执行完成,形成的私有栈内存就会被销毁掉(除无限递归、无限循环等)
(2)一旦栈内存中的某个东西(一般都是堆内存的地址)被私有作用域以外的事物占用了,则当前栈内存不能被立即释放销毁的(即:私有作用域中的私有变量等信息被保留下来了)
2 / 堆内存释放
堆内存的作用只有一个:存储引用数据类型的值
创建一个引用数据类型的值,就会产生一个堆内存。
如果当前创建的堆内存不被其它东西占用了,浏览器会在空闲的时候,查找每一个内存的引用状况,不被占用的都会被回收释放掉。
let obj = {
id:'zhaoxiajingjing'
};
let oop = obj;
此时,obj和oop都占用着对象的堆内存,想要释放堆内存,需要手动解除变量和值的关联。
null:空对象指针、空对象指针、空对象指针
obj = null;
oop = null;
3 / null、{}、undefined、''空字符串的区别
null和{}的区别
null:空对象指针
和{}空对象
不一样、不一样、不一样
let obj = {}; // 开辟一块堆内存,里面内容是空的,有16进制的地址AAAFFF000
obj = null; // 把变量obj指向空对象指针,把AAAFFF000这个堆内存释放掉
typeof null === 'object' // true
typeof {} === 'object' // true
这是浏览器的bug,所有存在计算机中的值都是二进制编码存储的,浏览器中的typeof方法把前三位是000的都判断做对象。null的二进制前三位就是000,所以识别为对象。但它不是对象。
null的数据类型是:基本类型值;null是空对象指针、空对象指针、空对象指针。
null、undefined和''空字符串的区别
let a;
console.log(a); // 输出undefined
let b = '';
console.log(b); // 输出 '' 空字符串
let obj = {};
console.log(obj.c); // 输出undefined
console.log(obj); // 输出 {}
obj = null;
console.log(obj); // 输出 null
(1)创建了一个变量a,并未赋值,默认值是undefined
(3)创建了一个空字符串的值;创建了一个变量b;让其与空字符串关联。空字符串也是一个普通值。
(5)开辟一个堆内存(假设:16进制地址是AAAFFF000)里面的目前是空的,没有键值对;把堆内存地址存入栈内存中;创建了一个变量obj;让其与栈内存的堆内存地址关联。
(6)obj.c
获取对象obj中的属性c,在obj中没有该属性,那么获取到的值是undefined
(8)释放对象obj的堆内存
4 / 预告
找THIS:
(1)
var a = 10;
function func(){
// 这里的THIS是谁?
console.log(this);
}
let obj = {
id:'zhaoxiajingjing',
name:'公号:朝霞的光影笔记',
func:func
};
(2)
var a = 10;
function func(){
// 这里的THIS是谁?
console.log(this);
}
let obj = {
id:'zhaoxiajingjing',
name:'公号:朝霞的光影笔记',
func:func
};
func();
window.func();
obj.func();
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。