小白都能看懂的javascript内存模型

javascript的数据类型分为两大类,基本类型(Undefined、Null、Boolean、Number和String)和引用类型(BOM,DOM,函数,数组等等),分别存储在栈内存和堆内存之中,对应值复制和值引用两种传值方式

const log = console.log;
	const print = JSON.stringify;
let a = 100;
	let b = a;
	a = 999;
	log(a: + print(a) +  ||| b: + print(b));
	
	let aa = 100;
	let bb = aa;
	aa = {};
	log(aa: + print(aa) +  ||| bb: + print(bb));

输出 a:999 ||| b:100 aa:{} ||| bb:100

b只是复制了a的值,两个变量是相互独立的,即便aa变成了引用类型,两者并没有联系

let c = { xyz: 100 };
	let d = c;
	c.xyz = 999;
	log(c: + print(c) +  ||| d: + print(c));
	
	let cc = { xyz: 100 };
	let dd = cc;
	cc = 999;
	log(cc: + print(cc) + 	||| dd: + print(dd));

输出 c:{"xyz":999} ||| d:{"xyz":999} cc:999 ||| dd:{"xyz":100}

d引用了c的值,两者指向同一块内存,但是cc一旦变成基本类型,dd就失去了和cc的同步关系

let e = [100, {xyz: 999}];
	let f = e[0];
	let g = e[1];
	f = 999;
	g.xyz = 100;
	log(e: + print(e));

输出 e:[100,{"xyz":100}]

e的两个元素的内存模型不同传值的方式也不同,前者为值复制后者为值引用

let a = "China No.1";
a = "China No.1";

//Uncaught TypeError: Assignment to constant variable.
const a = "China No.1";
a = "China No.1";

a.name = "primary type";
a.value = 55555;

console.warn("a", a);

注意基本类型对象可以使用成员操作符"."而且不报错,但是不会起作用

let b = {};
b = {};

//Uncaught TypeError: Assignment to constant variable.
const b = {};
b = {};

b.name = "object type";
b.value = 10000;

console.warn("b", b);

基本类型被const修饰直接变成常量,也就是值不可变重新赋值会直接报错,引用类型被const修饰表示地址不可变,但是值可变,通过"."改变对象的字段值

经验分享 程序员 微信小程序 职场和发展