js代码执行的过程:
语法分析:扫描有没有低级的语法错误
预编译:解释执行的前期准备阶段
解释执行:
函数的预编译过程****:
1.创建AO对象(相对于局部变量的集合)(AO对象就是执行期上下文)或者GO对象(相对于全局变量)(其实GO===window)
2.找函数的形参和变量声明,并将其赋值为undefiend;(此时不要考虑if判断的情况)
3.将实参的值赋值给形参
4.找函数声明,并将整个函数体赋值给函数声明(此时考虑if判断)
函数解释执行过程(此过程适用在变量最前面访问变量或者函数):
将变量值赋值给变量
注意点:
任何变量为经声明就赋值,此变量是全局对象上的一个属性
一切声明的全局变量,都是全局对象的属性。
function a(){
var c =b=2;
}
a();
函数的作用域:
1.预编译留下的产物,解释执行将它改进;
2.作用域中存储了 执行期上下文的集合,其实作用域称为作用域链更加合适.
3.执行期上下文就是上述中所提到的AO,
4.函数在被定义的时候,它的环境中就存在父级原有的作用域链;可以理解成站在父亲或者是巨人的肩膀上.
5.函数每次执行时都会在它所在的链的位置上新增加一段独一无二的执行期上下文 ;所以多次调用函数会创建多个执行期上下文,当函数执行完毕,它所产生的执行期上下文也会随之销毁.
闭包:
1.可以理解函数在返回它的子函数的同时也保存了它自己的作用域。
2.调用子函数的前提是先将此函数进行保存。
3.当调用子函数的时候,会在作用域的顶端多加一个执行期上下文。当然这条链上有它父级的执行期上下文(之所以称为父级,是以为此函数是在父级里面产生的)
4.导致结果:作用域链不释放
5.好处:属性私有化;防止全局变量污染,缓存。
闭包缓存的例子:
function oper(){
var num=100;
function a(){
num++;
console.log(num);
}
function b(){
num--;
console.log(num);
}
return [a,b];
}
var arr=oper();
arr[0].a();
arr[0].b();
函数闭包缓存的例子
立即执行函数
1.不用人为调用
2.系统自动调用然后立刻销毁(原因就是代码设计人员 为了语言的效率而设计的。这样的好处就是节省空间)
3.一般一个函数在代码中从头到尾只执行一次的时候,采用立即执行函数再好不过了。
4.立即执行函数还可以传递参数,具体例子如图
立即执行函数
5.只有表达式才能被执行符号执行。这里的执行符号代表();函数声明就不在表达式的范畴中,所以不会执行,犯语法错误。
1559292041(1).png
能被执行符号自动执行的表达式(也就是函数表达式),这个函数名字就会被自动忽略。
+function(){}();
-function(){}();
!function(){}();
~function(){}();
网友评论