内存空间
1、栈数据结构
基础数据值在内存中占据固定的大小空间,因此存在栈内存中
js的执行上下文顺序借用了栈数据的存取方式,所以理解栈数据结构的原理和特点十分重要
方式:先进后出,后进先出(类似一盒乒乓球)
2、堆数据结构
引用类型的值是对象,保存在堆内存中
堆数据结构是一种树状结构,它的存取方式,则与口红色号一样,只要有色号,就能找到对应的口红
不必像乒乓球把上面的都拿出来才能获取中间的某一个
好比JSON格式,key:value可以是无序的,因为顺序的不同不影响我们的使用,我们只关心色号
3、队列
学习队列数据结构的目的主要是为了清晰的明白我们js中事件循环(Event Loop)
队列是一种先进先出的数据结构,正如排队过安检是一样的。排在最前面的人一定是最先过安检的人。
4、变量对象与基础数据类型
js执行上下文之后,会创建一个叫变量对象的特殊对象,js的基础数据类型往往保存在变量对象中
基础类型都是一些简单的数据段,所以基础数据类型是按值来访问的,我们可以直接操作变量对象的实际值
5、堆内存与引用类型
js的引用类型储存在堆内存中
js不允许我们直接访问内存中的数据
世界上我们操作的是对象的引用而非实际的值
引用类型是按指针访问的,这个指针指向内存中的实际地址。
因此,我们操作引用类型复制时,它同样会分配一个新的值保存在变量对象中,但这个个新值同样指向内存中的实际值。改变一个,另一个也会发生改变
6、内存空间管理
- js内存声明周期
分配你所需的内存
使用分配的内存(读写)
不需要时释放,归还 - 垃圾回收机制
js拥有自动垃圾会回收机制
常用的使用标记清除法
当变量进入环境时,就将这个变量标记为进入环境
垃圾回收机制运行中会给存储在内存中的变量添加标记。然后,去掉环境中的变量以及环境中的变量被引用的标记,而在此之后再加上标记的变量将视为被准备删除的变量 - 性能优化
避免全局变量,使用完及时清空
局部变量,当函数执行安成之后很容易做出判断,然后回收。
7、知识点汇总
执行上下文的顺序是栈的数据结构方式,先进后出,后进先出
基础数据类型的值存在栈内存中
引用数据类型的值存在堆内存中
队列数据结构先进先出,后进后出。事件循环机制(Event Loop)
从一个变量向另一个变量复制基本类型的值。会创建这个值的副本
从一个变量向另一个变量复制引用类型的值,复制的其实是指针,因此两个变量最后指向同一个对象
解除变量的引用不仅有助于消除循环引用现象,而且对垃圾收集也有好处。为了确保有效地回收内存,应该及时解除不再使用的全局对象、全局对象属性以及循环引用变量的引用。
执行上下文
每当控制器转到可执行代码的时候,就会进入一个执行上下文
它会形成一个作用域,js运行环境分为3个种情况
全局作用域
函数作用域
eval
执行上下文可以理解成为当前代码的执行环境
因此js程序会出现多个执行上下文,所以js用栈的方式去处理它们。这个栈就叫做函数调用栈。栈底永远是全局上下文,栈顶是当前执行上下文
1、创建阶段
创建变量对象(vo)
建立作用域链(scopechain)
确定this指向
2、执行阶段
变量赋值
函数引用
执行其他代码
5、总结
js是单线程
同步执行,只有栈顶的上下文处于执行中,其他上下文需要等待,
全局上下文只有一个,它在浏览器关闭的时候出栈
函数执行上下文没有数量限制
每次新函数被调用,就会有新的执行上下文被创建
变量对象
1、变量对象是什么?生命周期的过程?变量提升是什么原理?
变量对象是执行上下文的创建阶段,会创建一个叫变量对象的基础对象。js的基本类型往往都保存在变量对象中
变量对象的生命周期是根据执行上下文的生命周期去划分的
创建阶段:(变量提升阶段,变量对象中的属性不能访问)
创建arguments对象
检查function函数声明创建属性
检查var变量声明的属性
执行阶段(变量对象转为活动对象,属性可以被访问,开始函数执行阶段操作)
函数执行
变量赋值
弹出执行栈
2、活动对象是什么?关系是神什么?
活动对象和遍变量对象其实是同一个的对象,区别在于执行的上下文的生命周期不同。
创建阶段就是变量对象,变量对象的属性不可被访问。
执行阶段就是活动对象,处于函数调用栈栈顶,也就是当前执行上下文。
3、全局上下文的变量
这里以浏览器为例,全局对象是window
全局上下文存在一个特殊的地方,他的变量对象就是window,而这个特殊的对象在this指向同样适用,this也指向window
全局上下文的生命周期与程序的生命周期一样,只要浏览器窗口不关闭,它就会一直存在。其他环境的上下文环境都可以访问全局上下文
4、let/const
不存在变量提升
未声明不可以用 (暂时性死区)
作用域与作用域链?
什么是作用域?
作用域也就是词法环境
词法环境就是一中规范的类型,用于ECMAscript代码的词法嵌套结构来定义标识符与特定变量和函数的关联
什么是作用域链?
作用域是一种规则,作用域链是代码在执行的过程中,会动态变化的一条索引路径
由当前环境和上层环境的一些列变量对象组成,它保证了当前执行环境对符合访问权限的变量和函数的有序访问
什么是闭包?
闭包是一种特殊的对象
由2部分组成
执行上下文(A)
以及执行上下文中创建的函数(B)
当B执行时,如果访问了A中变量对象中的值。就像成了闭包
垃圾回收机制,js具有自动垃圾回收机制,当一个值在内存中失去引用时,垃圾回收器很快找到它,并回收释放
函数执行上下文在执行完毕后,生命周期结束后,垃圾回收器就是收回其占用的内存空间,但使用闭包就会阻止这个过程
this
全局this
全局的this,指向window
通过this绑定到全局对象
通过声明绑定到变量对象,但在全局环境中,变量对象就是它自身
仅仅只有赋值操作,标识符会隐式绑定到全局对象
函数内部的this
如果函数调用者,被某一个对象拥有。那么该函数在调用时,this就是指向这个对象
如果函数内部独立调用,那么该函数内部的this,则指向window,严格模式下指向undefind
使用call,apply显示指定this
js内部提供了一种机制,允许我们改变thiss的指向。他就是call和apply
这2个函数的第一个参数都是改变this的指向,区别:
在于第二个参数,call接受一个个参数传入
apply接受数组传入
- call
接受参是一个个传入
- apply
参数接受一个数组
- bind
返回一个函数
可以选择不立即执行
apply和call是立即执行
构造函数与原型方法上的this
函数与函数式编程
函数声明,函数表达式,匿名函数与自执行
函数声明
function fn(){}
函数表达式
let fn=function(){}
匿名函数
function add(fn,num){console.log(fn()+num)}
add(()=>90,10)
自执行函数
(()=>console.log(90))()
函数参数传递方式:按值传递
基本类型复制是值进行的复制,复制后互不影响
引用类型的复制是指针的复制。虽然也在变量对象上开辟新的空间,但实际指针一样是堆内存中的地址,其中一个改变,另一个也将改变,相互影响
函数式编程
函数是一等公民
只用表达式,不应语句
纯函数
面向对象
工厂模式
没有办法识别对象实例的类型
通过一个方法可以去生成多个需要的对象
解决了重复代码编写
构造函数模式
使用new的方式。通过原型链找到对象的实例对象
new的四部曲
创建一个对象
将这个对象的原型指向构造函数的原型
通过apply将构造函数的的this指向这个对象
最后返回这个对象
原型模式
私有方法放实例中
共有方法放到原型链上
原型的好处是避免了同一功能性的方法写多份。直接挂载到原型上即可
当我们访问实例对象中的属性或者方法时,会优先访问实例对象自身的属性和方法。
原型链
原型链的访问,其实跟作用域链有很大的相似之处,他们都是一次单向的查找过程。因此实例对象能够通过原型链,访问到处于原型链上对象的所有属性与方法
继承
首先是构造函数的继承
通过call将父级的指针指向子集
原型的继承
可以将子集的原型指向父级的实例
使用Object.create
属性类型
configurable是否可以被删除
enumerable是否可以被枚举
writable是否可以重写
value该值具体多少,默认undefind
get访问,获取属性值
set设置。设置属性值
不能同时设置value、writable 与 get、set的值。
读取属性Object.getOwnPropertyDescriptor
事件循环机制
js是单线程,这个线程拥有的唯一的事件循环
来自不同任务源的任务会进入到不同的任务队列。其中setTimeout与setInterval是同源的。
事件执行的顺序,决定了JavaScript代码的执行顺序
它从script(整体代码)开始第一次循环,
之后全局上下文进入函数调用栈。直到调用栈清空(只剩全局),
然后执行所有的micro-task。
当所有可执行的micro-task执行完毕之后。
循环再次从macro-task开始,找到其中一个任务队列执行完毕,然后再执行所有的micro-task,这样一直循环下去。
其中每一个任务的执行,无论是macro-task还是micro-task,都是借助函数调用栈来完成
函数调用栈
任务队列
- 宏任务
setTimeout
setInterval
script(整体代码) - 微任务
Promise
XMind: ZEN - Trial Version
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。