作用域
目的:为了提高程序的可靠性,减少命名冲突。
JS的作用域分为:
- 全局作用域
- 局部作用域
1、全局作用域
整个<script>标签或一个单独的JS文件
<script> var num=10; </script>
2、局部作用域
在函数内部则是局部作用域,只在函数内部起效果和作用。
function fn(){ //局部作用域; }
变量的作用域
1、全局变量
在全局作用域下的变量。
varnum=10; console.log(num); functionfn(){ console.log(num); } fn();
因为num是全局变量,函数中没有另外声明一个变量,仅只有一个全局变量的num,所以函数中的num为全局变量中的num,最后结果为10。
2、局部变量
在局部作用域下的变量,只能在函数内部使用。
functionfun(){ varnum=10; } fun(); console.log(num);
因为num是在函数中的为局部变量,使用在调用函数fun()结果为10。但console.log打印的为全局变量,num仅为局部变量不能在函数外使用,所以返回的结果为num is not defined。
如果在函数内部没有声明直接赋值的变量也属于全局变量。
3、二者做比较
- 全局变量只有浏览器关闭的时候才会销毁,比较占内存资源。
- 局部变量当我们程序执行完毕就会销毁,比较节约内存。
- JS没有块级作用域(es6的时候新增的块级作用域)。
- 块级作用域:{ } if{ } for{ }
作用域链
- 只要是代码就至少有一个作用域。
- 写在函数内部的局部作用域。
- 如果函数中含有函数,那么在这个作用域中又可以诞生一个作用域
varnum=10; functionfn(){//外部varnum=20; functionfun(){//内部console.log(num); } }
内部函数访问外部函数的变量采取的是链式查找的方式来决定取哪个值。
JS预解析
JS引擎执行JS分为两步:
- 预解析:js引擎会把js里面所有的var和function提升到当前作用域的最前面。
- 代码执行:按顺序从上往下执行。
预解析分为:
- 变量提升:把所有的变量声明提升到当前的作用域最前面(不提升赋值操作)。
- 函数提升:把所有的函数声明提升到当前作用域的最前面。
1、变量提升:console.log(num); varnum=10; ↓↓↓↓varnum;//变量提升console.log(num); num=10;//赋值不提升2、函数提升fun(); varfun=function(){ console.log(22); } ↓↓↓↓varfun;//函数提升fun(); fun=function(){ console.log(22); }
预解析练习:
通过几个练习题来熟悉预解析叭!
1、
varnum=10; fun(); function(){ console.log(num); varnum=20; } ↓↓↓↓varnum;//变量提升(全局作用域)function=fun(){ varnum;//变量提升(局部作用域)console.log(num); num=10; } fun();
2、
varnum=10; functionfn(){ console.log(num); varnum=20; console.log(num); } fn(); ↓↓↓↓varnum; functionfn(){ varnum; console.log(num); num=20; console.log(num); } num=10; fun();
3、
vara=18; fn(); functionfn(){ varb=9; console.log(a); console.log(b); vara='123'; } ↓↓↓↓vara; functionfn(){ varb; vara; b=9; console.log(a); console.log(b); a='123'; } a=18; fn();