原型与原型链:
原型(prototype):
- 每个函数有一个prototype属性,它默认指向一个Object空对象(即原型对象)
- 原型对象中有一个属性constructor,它指向函数对象
- 给原型对象添加属性(一般都是方法):函数的所有实例对象自动拥有原型中的属性(方法)
显示原型与隐式原型:
原型继承:
- 构造函数的实例对象自动拥有构造函数原型对象的属性(方法)
- 利用的是原型链
表达式A instanceof B:
- 如果B函数的显示原型属性在A对象的原型链上,返回true,否则返回false
console.log(Object instanceof Function); // true
console.log(Object instanceof Object); // true
console.log(Function instanceof Function); // true
console.log(Function instanceof Object); // true
原型链:
变量提升与函数提升:使用var/function声明
先执行变量提升,再执行函数提升
执行上下文与执行上下文栈:
全局执行上下文:
- 在执行全局代码前将window确定为全局执行上下文
- 对全局数据进行预处理
- var定义的全局变量==>undefined,添加为window属性
- function声明的全局函数==>复制(fun),添加为window方法
- this指代window
函数执行上下文:
- 在调用函数时,准备执行函数体之前,创建对应的函数执行上下文对象(虚拟的,存在于栈中)
- 对局部数据进行预处理
- 形参变量==>赋值(实参)==>添加为执行上下文的属性
- arguments==>赋值(实参列表),添加为执行上下文的属性
- var定义的局部变量==>赋值undefined,添加为执行上下文的属性
- function声明的函数==>赋值(fun),添加为执行上下文的方法
- this指代调用函数的对象
- 开始执行函数体代码
执行上下文栈:
函数定义不会产生执行上下文,调用的时候产生。
作用域与作用域链:
区别:
作用域链:
闭包:
闭包理解:
常见闭包:
- 将函数作为另一个函数的返回值
- 将函数作为实参传递给另一个函数调用
闭包产生:在嵌套内部函数定义执行完时就产生了(不是在调用时才产生)
闭包死亡:在嵌套的内部函数成为垃圾对象时
闭包作用:
- 使函数内部的变量在函数执行完之后,仍然存活在内存中(延长了局部变量的生命周期)
- 让函数外部可以操作(读写)到函数内部的数据(变量/函数)
闭包的生命周期:
准备执行外部函数代码之前,函数提升时,内部函数对象已经创建,闭包产生。
闭包的应用:定义JS模块
闭包缺点:
- 函数执行完后,函数内的局部变量没有释放,占用内存时间变长
- 容易造成内存泄漏
解决:能不用闭包就不用闭包,及时释放(设为null,让内部函数成为垃圾对象,回收闭包)
内存溢出:
- 一种程序运行出现的错误
- 当程序运行需要的内存超过了剩余内存时,就会抛出内存溢出的错误
内存泄漏
- 占用的内存没有及时释放
- 内存泄漏积累多了就容易导致内存溢出
- 常见的内存泄漏:意外的全局遍历;没有及时清理的计时器或回调函数;闭包