2

前端基础进阶.png

内存空间

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


柚子
57 声望5 粉丝

前端小学生