内存
内存分类
1. 栈结构内存(数据结构:栈结构----》先进后出),通常用来保存变量对象 2. 堆结构内存(列表)----》通常用来保存对象(函数,对象,数组)
函数
函数分类
1.普通函数 2.构造函数 3.匿名函数自调用 4.回调函数(事件函数,定时器的回调)
原型
原型对象
1. 每个函数都有一个prototype属性,该属性指向的是原型对象(显示原型对象) 2. 每个实例对象都有一个—__proto__属性,该属性指向的也是原型对象(也是原型对象) 3. 构造函数的显示原型对象 === 当前构造函数的实例的隐式原型对象 4. 原型对象本身就是一个普通的Object实例对象,并且初始化的时候空对象,后期添加了constructor属性,该属性指向当前的构造函数本身 5. 实例身上的__proto__为什么叫隐式原型???因为当初设计的时候不允许操作__proto__,所以叫隐式原型对象
原型链
1. 查找对象的属性的时候先在自身查找,如果没有呢 2. 沿着__proto__属性查找,如果自身的原型对象没有呢 3. 会沿着原型对象的__proto__属性继续向上查找,直到查到Object的原型对象,如果有那就返回对应的值,如果没有就返回undefined 4. __proto__这条链就是原型链
执行上下文
变量提升 & 函数提升
1. js引擎在js代码执行之前(函数:意味着函数已经被调用了)会做一些预解析的工作 2. 会找两个关键字 var function 3. 找到带var 以后将带var的变量提前声明,但是不赋值 ---> var a; 4. 找到function以后提前定义函数体内容 5. 注意: - 全局预解析在定义函数的时候不关心函数是否被调用 - 函数局部预解析的时候,如果内部函数没有被使用就不会提前定义
设计者为什么要设计预解析这个东西
js是解释型语言,相对于编译型语言来说,代码是动态的,但是需要编译一行,解释一行,效率低 所以预编译就是为了提高js代码的执行效率 预编译一部分代码后,当执行到此代码就无需编译,直接解释就行了
执行上下文理解
1.执行上下文环境 - js引擎在js代码正式执行之前会创建一个执行上下文环境 - 执行上下文环境的分类 - 全局执行上下文 - 局部(函数)执行上下文 - eval执行上下文 2.执行上下文的变量对象 - js引擎进入执行上下文环境后先创建一个变量对象 - 该对象用于收集当前执行上下文环境中的: 变量,函数函数参数,this - 确认this指向 - 创建作用域链 3.执行上下文栈 - 作用: 用于保存执行上下文(变量对象) - 遵循规则: 先进后出 - 特点: 执行上下文是动态创建的----> 针对函数,函数每调用一次就会创建一次执行上下文,执行完就销毁
作用域
作用域的理解
- 抽象的概念 - 用来决定代码执行的范围,变量所属的范围 - 作用域时代码定义的时候决定的 - 作用域作用: - 隔离变量 - 规定其之后的作用域链是什么样的,体现: [[scopes]]:上一级作用域链
##作用域链 - 作用域链是一个数组结构 - 该结构内保存的是一个个变量对象 - 作用域链什么时候创建的: 在js代码正式执行之前创建的(此时的函数已经被调用了,不调用就不会有预解析,创建预解析的时候会创建作用域链)
闭包
闭包形成的条件
- 函数嵌套 - 内部函数引用外部函数的局部变量 - 内部函数被使用, 注意: 如果函数变量提升的时候如果内部函数没有被使用(调用和返回),在预解析的过程中不会定义内部函数
什么是闭包
- 闭包是一个存在内部函数的引用关系 - 该引用指向的是外部函数的局部 变量对象(前提: 内部函数使用了外部函数的局部变量)
常见的闭包有哪些
- 将函数作为另一个函数的返回值 - 将函数作为实参传递给另一个函数去调用 - 使用闭包实现私有方法操作独立的私有属性
问题?
- 函数执行完后,函数内部声明的局部变量是否存在? 不存在 - 在函数外部能否直接访问函数内部的局部变量? 不能
闭包的作用
- 延长外部函数变量对象的生命周期 - 使用闭包能够间接的从函数外部访问函数内部的私有变量 (让函数外部可以操作(读写)到函数内部的数据(变量/函数),或可以在函数的外部去操作函数内部的变量)
闭包的生命周期
- 产生: 在嵌套内部函数定义的时候就产生了 - 死亡: 在嵌套的内部函数成为垃圾对象时
闭包的优缺点
- 优点: 延长外部函数变量对象的生命周期(使用闭包能够间接的从函数外部访问函数内部的私有变量) - 缺点: 延长外部函数变量对象的生命周期(占内存,如果不及时清除容易造成内存溢出,泄漏) - 函数执行完后, 函数内的局部变量没有释放, 占用内存时间会变长 - 容易造成内存溢出
使用闭包注意
- 及时清除闭包 - 让内部函数称为垃圾对象 ---> 内部函数身上没有指针指向