文 / 景朝霞
来源公号 / 朝霞的光影笔记
ID / zhaoxiajingjing
图 / 本身画
❥❥❥❥点个赞,让我知道你来过~❥❥❥❥
【前情提要】javascript
【iview】java
var a = 10; var obj = { id:'zhaoxiajingjing', name:'公号:朝霞的光影笔记' }; function func(a) { console.log(a); } func(1);
△图13.1:代码的图解web
内存分为:栈内存(stack),堆内存(heap);以谷歌的webkit为例,要清楚咱们本身在打开浏览器时产生的堆栈内存:编程
(1)在浏览器中打开页面,浏览器引擎会渲染相关的代码(包括JS代码),把代码自上而下执行数组
(2)浏览器想要执行代码,会提供一个供代码执行的环境:Execution Context Stack(执行环境栈ECStack)栈内存浏览器
(3)最开始执行的是全局代码,因此会造成一个Execution Context(Global)全局执行上下文(EC(G)),在栈内存中执行全局代码闭包
(4)在全局的执行上下文中有一个Variable Object (Global) 全局变量对象(VO(G)是有浏览器底层语言写的),能够把须要定义的变量和对应的值存储在这里iview
(5)var a =10;
函数
① 建立一个值10(基本数据类型直接存储在栈内存中)oop
② 建立一个变量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
栈内存的两个做用:
一、提供代码执行的环境
二、存储基本类型值
打开浏览器造成的全局做用域是栈内存
函数执行造成的私有做用域是栈内存
基于ES6的let/const造成的块级做用域是栈内存
....
那么,栈内存释放:
一、全局栈内存:关闭浏览器
二、私有栈内存:
(1)通常状况下,函数执行完成,造成的私有栈内存就会被销毁掉(除无限递归、无限循环等)
(2)一旦栈内存中的某个东西(通常都是堆内存的地址)被私有做用域之外的事物占用了,则当前栈内存不能被当即释放销毁的(即:私有做用域中的私有变量等信息被保留下来了)
堆内存的做用只有一个:存储引用数据类型的值
建立一个引用数据类型的值,就会产生一个堆内存。
若是当前建立的堆内存不被其它东西占用了,浏览器会在空闲的时候,查找每个内存的引用情况,不被占用的都会被回收释放掉。
let obj = { id:'zhaoxiajingjing' }; let oop = obj;
此时,obj和oop都占用着对象的堆内存,想要释放堆内存,须要手动解除变量和值的关联。
null:空对象指针、空对象指针、空对象指针
obj = null; oop = null;
null:空对象指针
和{}空对象
不同、不同、不同
let obj = {}; // 开辟一块堆内存,里面内容是空的,有16进制的地址AAAFFF000 obj = null; // 把变量obj指向空对象指针,把AAAFFF000这个堆内存释放掉
typeof null === 'object' // true typeof {} === 'object' // true
这是浏览器的bug,全部存在计算机中的值都是二进制编码存储的,浏览器中的typeof方法把前三位是000的都判断作对象。null的二进制前三位就是000,因此识别为对象。但它不是对象。
null的数据类型是:基本类型值;null是空对象指针、空对象指针、空对象指针。
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的堆内存
找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();