Appearance
webkit底层渲染机制
浏览器中打开页面,会在计算机中分配出两块内存,栈内存和叫堆内层
栈内存叫做 ECStack(Execution Context Stack),执行上下文栈,是用来提供代码执行的环 境,让代码自上而下执行,同时存储声明的变量和原始值类型的值。 堆内存用来存储引用类型的值,有一个 16 进制的地址值,存储键值对,对于函数来说除了存储 键值对,如 { name: 函数名, length: 函数定义时的形参个数 } 等信息以外,还要存代码字符 串,scope 作用域,最后把地址放入栈中,和变量关联起来。同时因为浏览器提供了内置的一些 属性和方法,浏览器就会在开辟的堆内存中,默认分配一块空间,用来存放那些内置的属性和方 法,这块空间被称为全局对象 GO。
接着代码执行,最开始执行的是全局代码,为了能够有效区分代码执行时所处的环境会形成一个 EC(G) 全局执行上下文供全局代码执行,在全局执行上下文中有一个存放未来它声明的变量的地 方,叫做 VO(G) 全局变量对象。为了能够在代码执行中,可以访问到 GO 中的属性和方法,浏 览器会在 VO(G) 中默认声明了一个变量 window,值就是 GO 的地址值,从而访问内置的属性 和方法。
EC(G) 进入到 ECStack 中执行
变量提升和词法分析
代码执行
遇到函数产生私有上下文
遇到函数和对象以外的花括号产生块级上下文
堆 vs 栈
存储大小
栈内存的存储大小是固定的,申请时由系统自动分配内存空间,运行效率比较高
堆内存的存储大小是不定的,由程序员自己申请,运行效率比较低。
存储内容
栈内存的是基本数据类型,是按值访问的,栈是连续的一块内存空间,以后进先出的原则存储调用。
堆存储的是引用数据类型的地址值,是不连续的内存空间
回收
栈的回收是系统控制实现的,只要结束就直接回收。
堆的回收是由 V8 回收机制控制的
/* VO(G) VS GO 在全局上下文中(前提是全局上下文)
var a = 12
1.先创建一个值12,因为是var声明,所以存储到GO当中
2.再创建一个变量a,把其存储GO中
3.最后把创建的变量和创建的值12关联在一起(赋值操作)
function fn () {}
1.内存中开辟一个堆内存,每一个堆内存都有一个16进制地址,存储的函数体中的代码串
把堆内存的地址放到栈内存中,用来供变量的引用
2.GO中创建一个变量
3.让GO中变量和之前创建的堆内存地址关联起来
在没有ES6的时候,var/function是既往GO放一份,也往VO放一份,一个变化另一个也会变化,映射和同步
ES6诞生后,浏览器既要兼容ES6,也要兼容ES5,为了能够有效区分,ES5声明的都只放到GO中,ES6声明的放到VO中
let b = 12
1.先创建一个值12,基本类型值直接存储在栈内存VO(GLOBAL)当中
2.再创建一个变量b,把其存储到VO(GLOBAL)中
3.最后把创建的变量和创建的值12关联在一起(赋值操作)
let obj = {}
1.内存中开辟一个堆内存,每一个堆内存都有一个16进制地址,把对象中的键值对分别存储到堆内存中
把堆内存的地址放到栈内存中,用来供变量的引用
2.创建一个变量
3.让变量和之前创建的堆内存地址关联起来
z = 14
<=> 向当前或上级作用域查找z 到最后都没找到就是window.z = 14
在全局上下文中
如果window.z,直接到GO中找,没找到就是undefined
如果直接输出一个变量,先让VO(G)中是否有,如果有获取的就是全局变量,如果没有则去GO中找,
如果有就是全局对象属性,没有则直接报错 xxx is not defined
数据类型区别 基本数据类型结构比较简单,直接存储到栈内存即可,后续变量都是直接关联和操作这个值 => 按值操作 引用数据类型结构比较复杂,不能直接存储到栈内存中,需要在堆内存中单独开辟一块空间, 用来存储对象的键值对,而变量关联和操作都是堆内存空间的引用地址(16地址),是按引用地址操作 */
js
// example1
let a = {
n: 1
}
let b = a
a.x = a = {
n: 2
}
console.log(a.x)
console.log(b)
// example 2
let a = {},
b = '0',
c = 0
a[b] = '1'
a[c] = '2'
console.log(a[b])
// example 3
let a = {},
b = Symbol('1'),
c = Symbol('1')
a[b] = '2'
a[c] = '3'
console.log(a[b])
// example 4
let a = {},
b = {
n: '1'
},
c = {
m: '2'
}
a[b] = '3'
a[c] = '4'
console.log(a[b])
// example5
var a = 0
var b = a
b++
console.log(a)
var o = {}
o.a = 0
var b = 0
b.a = 10
console.log(o.a)
// example6
let x = [1, 2, 3]
let y = x
let z = [4, 5, 6]
y[0] = 10
y = z
z[1] = 20
x[2] = z = 30
console.log(x, y, z)