理解 | 堆内存栈内存释放、null和{}、undefined的区别

文 / 景朝霞
来源公号 / 朝霞的光影笔记
ID / zhaoxiajingjing
图 / 本身画
❥❥❥❥点个赞,让我知道你来过~❥❥❥❥

【前情提要】javascript

  1. 题目 | let和var的区别(1、二)
  2. 图解 | let和var的区别(1、二)
  3. 题目 | 带VAR和不带VAR的区别
  4. 图解 | 带VAR和不带VAR的区别
  5. 总结 | LET和VAR区别(3、四)
  6. 图解 | 做用域和做用域链
  7. 练习题 | 做用域和做用域链
  8. 图解 | 理解闭包
  9. 案例 | 闭包做用:保护和保存
  10. 图解 | 判断条件中的变量提高、私有变量、全局变量、arguments
  11. 理解 | 堆内存栈内存释放、null和{}、undefined的区别

【iview】java

  1. iview低版本实现表格拖拽,滚动条列宽计算问题
  2. 案例 | iview中Table:拖拽适配列、自定义固定列、合并列
  3. 读源码 | 跟着大佬们学编程思想
  4. 上 | iview的Table组件合并列demo
  5. 下 | iview的Table组件合并列,升级代码

0 / 举个例子

var a = 10;
var obj = {
    id:'zhaoxiajingjing',
    name:'公号:朝霞的光影笔记'
};
function func(a) {
    console.log(a);
}
func(1);

公号ID:zhaoxiajingjing
△图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

1 / 栈内存释放

栈内存的两个做用:

一、提供代码执行的环境

二、存储基本类型值

打开浏览器造成的全局做用域是栈内存

函数执行造成的私有做用域是栈内存

基于ES6的let/const造成的块级做用域是栈内存

....

那么,栈内存释放:

一、全局栈内存:关闭浏览器

二、私有栈内存:

(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();

公号ID:zhaoxiajingjing

相关文章
相关标签/搜索