关于堆栈内存,你知道多少?

161 阅读4分钟

执行环境栈和执行上下文

JS代码运行都需要在一个环境中,大概包括以下几种:

  1. 浏览器(引擎)
  2. node(基于v8渲染js)
  3. webview(v8引擎)

......

下面这些名词都代表了什么,来跟着小编学习下吧!

执行环境栈 ECStack(Execution Context Stack):浏览器想要执行JS代码,需要提供一个供代码执行的环境,该环境即为执行环境栈,又称 栈内存(从内存中分配出来的一块内存)

执行上下文 EC(Execution Context):在编程语言中,代码执行中为了区分全局和函数执行所处的不同作用域,目的是为了区分每个词法作用域下代码的独立性,形成执行上下文 (代码执行所在的词法作用域,或者代码执行所处的范围) 进栈执行,执行完出栈。

在每一个上下文代码执行的时候,都可能会创建变量。所以在每一个上下文(无论是全局还是私有),都会有一个存储变量的空间;分别为:VO(Varibale Object)和 AO(Active Object)。

变量对象:存放当前上下文中的变量,只不过全局上下文称为VO(G),私有上下文中称为AO(G),但是也是变量对象;

全局对象:GO(Global object),跟VO/AO没有关系,浏览器把所有后期需要供JS调取使用的属性和方法(内置)都放在GO对象中,并且在全局中创建一个window变量指向它。全局对象方法有setInterval、eval、JSON....等

这么看,我们可以把执行环境栈理解为一个菜市场,那么市场中每个店面都是一个私有上下文,互相独立,各家卖各家的蔬菜水果。每家店中的蔬果都可以当作是AO中的对象。市场中的管理部门以及停车场都可以当作是全局执行上下文,白天卖菜就要进市场开门,代表了进栈执行,等到晚上关门,代表执行完出栈。个人觉得可以这样理解。

对象数据类型

对象数据类型:由0到多组键值对(属性名和属性值)组成的.

属性名的类型:

说法1:属性名类型只能是字符串或者Symbol
说法2:属性名类型可以是任何基本类型值,处理中可以和字符串互通(个人更认同说法2)
但是属性名绝对不能是引用数据类型,如果设置引用类型,最后也是转换为字符串处理的

obj[x] —— x为变量,把x变量存储的值当作属性名,获取对象的属性值 obj['x'] —— 获取属性名为x的属性值 <=> obj.x

/*
 *		属性名为对象-----转为字符串'[object Object]'
 *		let x={
 *			0:0
 *		}
 *		let obj={};
 *		obj[x]=100; 
 *		console.log(obj);   //{'[object Object]':100}
 */

let x = 20;
let obj = {
    x:100
}
//属性名肯定是一个值
obj[x] ———— 把x变量存储的值当作属性名,获取对象的属性值 => obj[20] => undefined
obj['x']<=>obj.x ———— 获取属性名为x的属性值 => 100

//练习
var a = {},b='0',c=0;
a[b]='hello';  => a['0']='hello'
a[c]='world';  => a[0] = 'world'
console.log(a[b]);   //'world'

var a = {},b=Symbol('1'),c=Symbol('1');   //symbol唯一值,b!=c
a[b]='hello'; 
a[c]='world';
console.log(a[b]);   //'hello'

var a = {},b={n:'1'},c={m:'2'};  
a[b]='hello';  => a['[object Object]']='hello'
a[c]='world';  => a['[object Object]']='world'
console.log(a[b]);   //'world'

创建变量&赋值: 从右到左的过程

  1. 创建一个值(基本类型值直接存储在栈内存中,引用数据类型值需要先开辟一个堆内存,把内存存储进去后,把堆内存地址存放到栈内存中供变量调用);
  2. 创建一个变量存储在变量对象中;(声明)
  3. 让变量和值进行关联(指针指向的过程);(定义)
let a = 12,b = 13;   ===>  let a = 12;let b = 13;   

let a = b = 12;  //从右到左 1.创建值12  2.b=12   3.let a = 12

//成员访问a.x优先级很大,所以无论怎么调换位置都是先处理a.x={}
a.x = a = {}
a = a.x ={}

// a ----- AF0
var a = {
    n:1
}        
// b------ AF0
var b = a;
//a.x ----- AF1
// a ------ AF1
a.x = a = {
    n:2
}
console.log(a.x)   //undefined
console.log(b)     
/*
{
	n:1,
	x:{
		n:2
	}
}
*/
var x = [12,23];
function fn(y){
    y[0] = 100;
    y = [100];
    y[1] = 200;
    console.log(y);   //[100,200]
}
fn(x);
console.log(x);  //[100,23]