预解释
在js代码执行之前,首先会在当前作用域下将所有带 var 和 function 关键字的进行提前声明(declare)或者定义(defined)。
- var:在代码执行之前只是
先声明(默认值是undefined) - function:是
声明和定义都完成了 - 只
声明了没有定义,默认值都是undefined - js中用来执行代码的那个空间(作用域),叫做栈内存
- 用来运行代码的。
- 用来存储基本数据类型值的
- 引用数据类型开辟的空间(作用域),叫做堆内存
- 用来存储引用数据类型的
预解释的7步骤
- 不管条件是否成立,都会进行预解释
- 预解释只发生在
=号左边,= 号右边不会进行预解释 - 匿名函数闭包常用的方式不进行预解释
- 函数中的
return后面的代码也要进行预解释,但是return后面紧跟的值不预解释 - 当var 和 function 重名的情况下,不重复声明,但是会重复定义
- 预解释只发生在当前作用域下
- 预解释只发生在同一脚本块中
作用域
- 当一个方法执行的时候会产生一个私有的作用域,这种机制叫做闭包
- 一般情况下一个函数的生命周期
- 从预解释开始,代码执行前首先把function声明和定义了,在这一过程中,会开辟一个堆内存,将函数体中的js代码当做字符串存储进来
- 当代码走到函数执行的那一处,会产生一个新的私有作用域(用来执行代码)
- 在新的私有作用域中,首先进行私有作用域下的预解释,把私有作用域中的var 和function都提前的声明或定义,预解释完成后就开始从上到下执行我们的js代码
- 私有作用域中的代码执行完成后,这个新形成的作用域立即销毁,如果以后再重 新执行函数,则会重新形成新的作用域,按照此流程再执行一遍;
- 注意:在私有作用域下,预解释的变量和定义的形参变量都是私有变量,在函数体中,我们遇到一个变量首先看一下是不是自己的私有变量,是的话就用自己,不是的话就 往它的上一级作用域找,如果也没有就继续往上找,一直找到window,window也没 有就报错了;
特殊情况
- 不销毁:当一个函数F执行,形成一个私有作用域,首先预解释,然后代码从上倒下执行,当执行完成后,F又返回了一个新的函数f,并且把返回的f在外面用一个变量接收了,那么F形成的那个作用域就不销毁了;
- 不立即销毁:当一个大函数,返回一个小函数,但是并没有被外面用变量接受,这样的情况,大函数形成的那个作用域不立即销毁(等闲下来的时候,在销毁) 每一个function都会形成一个堆内存,function执行的时候还会再行成一个新的私有作用域
this 关键字
- this规则:
- this是谁,跟在那定义(跟在那执行)没有关系,只跟函数执行的主体有关
- 对于匿名函数的闭包的方式,里面出现的this是window
- 对DOM元素标签绑定事件,this就是被绑定事件的那个元素
- 在构造函数中,this就是new出来的实例
注意事项
- js中如果有代码报错了,那么后面的代码就不在执行了
- 在全局作用域下定义的变量相当于window对象的一个属性
- 函数执行完成如果没有return 或者只有return 默认都是undefined.