先容
栈(stack) 栈stack为自动分配的内存空间,它由系统自动释放
堆(heap) 堆heap是动态分配的内存,巨细不定也不会自动释放
动态演示地址
数据类型
- 基本类型:String、Number、Boolean、Null、Undefined、symbol(ES6)
- 基本类型在内存中占有空间小、巨细牢固 ,他们的值保存在栈(stack)空间,是按值来接见
- 引用类型:Object、Array、Date、Function、Error、RegExp、Math、Number、String、Boolean、Globle。
- 引用类型占有空间大、巨细不牢固, 栈内存中存放地址指向堆(heap)内存中的工具。是按引用接见的
客栈
- 堆:用于引用数据类型(数组,工具,函数)分配空间,从栈内存指向堆内存的数据结构
- 引用数据类型Object(Array,Date,RegExp,Function…)
- 堆内存释放
- 让所有引用堆内存空间地址的变量赋值为null即可,当堆内存没有被任何的变量或者其他器械引用时,就会在浏览器执行垃圾接纳的时刻,被销毁掉。
var obj = {'name': 'along'}
堆内存 |
|
{‘name’: ‘along’} |
指针 |
obj2 = obj
堆内存 |
|
{‘name’: ‘along’} |
指针 |
{‘name’: ‘along’} |
指针 |
结论:你会发现,若是是引用类型复制的话,虽然会有两个指针,然则指向都是同一个工具,这就会造成若是改变obj2值,也会造成obj值的改变。
如下图所示:栈内存中存放的只是该工具的接见地址, 在堆内存中为这个值分配空间 。 由于这种值的巨细不牢固,因此不能把它们保存到栈内存中。但内存地址巨细的牢固的,因此可以将内存地址保存在栈内存中。 这样,当查询引用类型的变量时, 先从栈中读取内存地址, 然后再通过地址找到堆中的值。
- 栈(先进后出/后进先出的数据结构)
- 栈基本五种数据类型: String、Number、Boolean、Null、Undefined、symbol(ES6)
- 栈内存释放
- 全局作用域会在页面关闭或者刷新的时刻释放。
- 私有作用域一样平常情形下,当函数执行完成,所形成的私有作用域(栈内存)都市自动释放掉,然则也有特殊的情形。(闭包)
- 结构特点
- 示例
var a = 2;
栈内存
|
|
a |
2 |
b = a
栈内存 |
|
a |
2 |
b |
2 |
结论:栈内存虽然复制了a,然则建立了新的行列。修改b的值的同时也不会改变a的值。
代码实现
使用数组实现栈的结构
function Stack(){ let items = []; this.size = function(){ return items.length } this.push = function(item){ items.push(item) } this.pop = function(){ let item = items.pop() console.log('pop',item) return item } this.top = function(){ let length = items.length; console.log('top',items[length-1]) } this.show = function(){ console.log(items) } this.clear = function(){ items.length = 0 } this.isEmpty = function(){ console.log(items.length === 0) return items.length === 0 } } let newStack = new Stack(); newStack.push(12); newStack.show() newStack.top() newStack.pop(); newStack.isEmpty(); newStack.show() newStack.push(1); newStack.push(5); newStack.isEmpty(); newStack.top() newStack.show() newStack.clear(); newStack.show()
栈内存溢出
挪用客栈会一直增进,直到到达限制,浏览器硬编码客栈巨细或内存耗尽。以是在用递归函数时要给一个终止条件。
var count = 1; function fn() { count++; fn() } fn() //Maximum call stack size exceeded
History API与浏览器客栈治理
pushState,它会向浏览器的历史客栈压入一个url为设定值的纪录,并改变历史客栈的当前指针至栈顶。
history.pushState(stateObject, title, url) stateObject:state是一个由 pushState()方式建立的、与历史纪录相关的JS工具。当用户定向到一个新的状态时,会触发popstate事宜。事宜的state属性包含了历史纪录的state工具。 title:现在大多浏览器都忽视,通报空即可 url:新历史纪录的url地址
replaceState:与pushState参数相同,寄义也相同。唯一的区别在于replaceState是替换浏览器历史客栈的当前历史纪录为设定的url。需要注重的是,replaceState不会改动浏览器历史客栈的当前指针。
onpopstate:该事宜是window的属性。该事宜会在挪用浏览器的前进、退却以及执行history.forward、history.back、和history.go触发,由于这些操作有一个共性,即修改了历史客栈的当前指针。在不改变document的前提下,一旦当前指针改变则会触发onpopstate事宜。
建立一个新的浏览器纪录状态
const state = { 'page_id': 1, 'user_id': 5 } const title = '' const url = 'hello-world.html' history.pushState(state, title, url)
总结:
浏览器针对每个页面维护一个History栈。执行pushState函数可压入设定的url至栈顶,同时修改当前指针
当执行back操作时,history栈巨细并不会改变(history.length稳定),仅仅移动当前指针的位置
详细查看:https://www.yuque.com/along-n3gko/ezt5z9/gle5df
原创文章,作者:admin,如若转载,请注明出处:https://www.2lxm.com/archives/7950.html