分类(ES6之前):全局作用域、局部(函数)作用域
全局作用域:整个script标签,或者是一个单独的js文件
局部作用域:在函数内部就是局部作用域这个代码的名字只在函数内部起效果和作用
变量的作用域:根据作用域的不同我们变量分为全局变量和局部变量
全局变量:在全局作用域下声明或在函数内没有声明直接赋值的变量,在全局下可以使用。只有关闭浏览器才会销毁,比较占内存资源
局部变量:在局部作用域下声明的变量,函数的形参也可以看作是局部变量。当程序执行完毕就会销毁,比较节约内存
作用域链:内部函数访问外部函数的变量,采取的是链式查找的方式来决定取那个值,往外一层一层的找,找不到则报错。这种结构我们称为作用域链。采用就近原则
02预解析js引擎运行js分为两步:预解析、代码执行
预解析:js引擎会把js里面所有的var还有function提升到当前作用域的最前面
代码执行:按照代码书写的顺序从上往下执行
预解析分为变量预解析(变量提升/声明提升)和函数预解析(函数提升/值提升)
声明提升:把所有的变量声明提升到当前的作用域最前面,不提升赋值操作(能够在声明变量那一行之前在其作用域中使用变量,而不会抛出ReferenceError,但值是undefined)
值提升:把所有的函数声明提升到当前作用域的最前面,不调用函数(能够在声明变量那一行之前在其作用域中使用变量的值)
03案例案例一
varnum=10;fun();functionfun(){console.log(num);varnum=20;}
//相当于执行了以下操作varnum;//声明提升functionfun(){varnum;//声明提升console.log(num);num=20;//赋值}//值提升num=10;//赋值fun();//函数调用
案例二
vara=18;f1();functionf1(){varb=9;console.log(a);console.log(b);vara=";}
//相当于以下代码vara;//声明提升functionf1(){varb;//声明提升vara;//声明提升b=9;//赋值console.log(a);console.log(b);a=";//赋值}//值提升a=18;//赋值f1();//函数调用
案例三
f1();console.log(c);console.log(b);console.log(a);functionf1(){vara=b=c=9;console.log(a);console.log(b);console.log(c);}
//相当于以下代码functionf1(){vara;//声明提升a=b=c=9;//赋值//相当于vara=9;b=9;c=9;b和c直接赋值没有var声明当全局变量看//集体声明vara=9,b=9,c=9;console.log(a);console.log(b);console.log(c);}//值提升f1();//函数调用console.log(c);console.log(b);console.log(a);