js中唯一能封闭作用域的就是函数,外界无法访问函数内部声明的变量
作用域:能声明变量能能找到变量的规则
全局作用域:公有变量
函数作用域: 私有变量
外界无法访问函数内部声明的变量
js 执行顺序: 1.语法分析(有错就报错先) 2.预解析 3.执行
♥程序具体分析:1.语法分析
2.预解析过程
预解析过程是先生成一个全局仓库(GO),把变量名字添加进去,给上默认值undefined,再把函数名字添加进去,给上值为声明的函数体(因为函数是js中唯一能封闭作用域的)
全局变量也可用window来调用,如 window.a = undefined;
3.执行 函数名(),b(),在仓库中找到相应函数名对应的函数体。
打开浏览器页面仓库就会生成,代码就会执行,关闭浏览器页面,仓库就会消失。
函数具体预解析过程:非常重要,外部定义的变量只有通过参数传进来才能被函数解析
在函数未被调用前,仓库掌握着变量与函数的解释权,在函数调用之后,函数自己掌握解释权,开始执行函数体内部,在函数体内部开始了 预解析 与执行,函数体内部的预解析是以函数内部为顶
不会上到仓库中,因为函数会封闭作用域。
undefined是因为函数封闭作用域,第一个打印的a 参数,而参数未定义故为undefined,var a=20只能通过参数的形式传进来才能被函数解析。
预解析对象是活动对象(AO) 也叫作用域,函数参数eg function m(a){}
相当于在函数内部隐式声明了 a function m(){ var a;}
解析流程及细节:这个非常重要
1.先找全局变量放在仓库里GO,把声明的 函数名:函数体 也放在GO里, 如果一个变量未声明但赋值了,或者声明了没赋值,调用的时候该值都为undefined.
2.遇见变量的赋值在赋值,没赋值之前为undefined (函数内部的预解析过程在变量赋值之后)
3.在函数内部预解析 把函数内部声明的变量名以及形参放在AO 变量名:undefined 形参:undefined , 在函数内部声明的函数名:函数体放在 AO(涉及函数的嵌套)
如果外界调用了函数,且函数体内有未被声明的变量,该变量就会被隐式设置成全局变量。(全局变量污染)
执行阶段: 实参传形参赋值 以及函数内部对值的改变
函数表达式声明的函数属于执行阶段的赋值
函数预解析过后就 函数名()调用执行。
注意:函数在执行阶段如果没在作用域中找到声明的变量会从全局范围内找
AO是函数调用时才会创建,不用的时候会自动消除,否则占内存,js游戏在优化上就会考虑这个,否则会卡