JS的变量有两种,“全局变量”和“局部变量”。
“全局变量”声明在函数外部,可供所有函数使用,(全局变量属于window)而“局部变量”声明在函数体内部,只能在定义该变量的函数体内使用。
1.全局变量:(1)直接在函数外部声明的变量 var a=3
(2)在任何位置上,声明变量时没有var关键字,而是直接赋值的变量均为全局变量 s=3
2.局部变量:(1)在函数内部声明的变量
(2)形参,参数变量天生就是局部变量
1 <script type="text/javascript">2 ??function main() { 3 ????n = 10;//这里的n为全局变量,可以被外部直接使用4 ??}5 ??main();6 ??alert(n);7 </script>
JS的作用域有两种,“全局作用域”和“函数作用域”。
1.全局作用域:可以在程序的任何位置被访问
2.函数作用域: 仅能在函数调用时,内部被访问
注意:在函数体内,局部变量的优先级高于全局变量。
网上有一个很具有代表性的例子,在函数体外部和内部都申明了相同名字的变量,变量的作用域问题,例子如下:
1 <script type="text/javascript"> 2 ??var n = 1; 3 ??function test() { 4 ????alert(n); ?//这里的n并不是全局变量,原因是函数体第四行声明了一个重名的局部变量n, ?5 ?????????????????//如果把第四行n的声明注释掉,那么这里的显示1,为全局变量。 6 ????????????????//所以得出结论:全局变量a被局部变量a覆盖了。 7 ??????????????//说明了JS函数在test()在执行前,函数体内的变量a都指向了局部变量. 8 ????????????//但本行输出的a在执行过程中还没有被赋值,所以显示undefined。 9 ????n = 2;10 ????alert(n);11 ????var n; //本行声明局部变量a12 ????alert(n);13 ??}14 ????test();15 ????alert(n);16 </script>
上面代码的结果为:undefined 2 2 1; 原因就是函数体外部和内部都申明了相同名字的变量时,局部变量覆盖了全局变量。
外部怎么读取函数体内部的局部变量呢?
一般来说,只有函数体内部可以直接得到外部的全局变量,但是外部要得到函数体内部的局部变量是不行的。但是,通过在函数体内部再定义一个函数返回局部变量,再从外部调用函数就能实现了。
1 <script type="text/javascript"> 2 ??function f1() { 3 ????var n = 10; 4 ????function f2() {//在f1()内部再定义f2(),通过f2()访问f1()中的局部变量 5 ??????alert(n); 6 ????} 7 ????return f2;//返回f1()局部变量n 8 ??} 9 ??var result = f1(); //在外部调用f1()函数,就能获取局部变量n的值10 ??result(); // 10,即为n的值11 </script>
函数中变量的声明提升
在程序执行前或函数调用前,将var声明的变量和function声明的函数提升到当前作用域的顶部集中创建。
请看下面的例子:
1 var v = "hello";2 (function(){3 ??console.log(v);4 ??var v = "world";5 })(); ???结果为undefined
1 var v = "hello";2 if(true){3 ??console.log(v);4 ??var v = "world";5 } ????结果为hello
上面的代码说明了3个问题:1,function作用域里的变量v遮盖了全局作用域变量v
2,在function作用域内,变量v的声明被提升了
3,javascript是没有块级作用域的。函数是JavaScript中唯一拥有自身作用域的结构
上面的代码相当于:
1 var v = "hello";2 (function(){3 ??var v; //declaration hoisting4 ??console.log(v);5 ??v = "world";6 })();
总结:当前作用域内的声明都会提升到作用域的最前面,包括变量和函数的声明。
1 (function(){2 ??var a = "1";3 ??var f = function(){};4 ??var b = "2";5 ??var c = "3";6 })();
变量a,f,b,c的声明会被提升到函数作用域的最前面,如下
1 (function(){2 ??var a,f,b,c;3 ??a = "1";4 ??f = function(){};5 ??b = "2";6 ??c = "3";7 })();
请注意函数表达式并没有被提升,这也是函数表达式与函数声明的区别。进一步看二者的区别:
(function(){ ?//var f1,function f2(){}; //声明提升,被隐式提升的声明 ??f1(); //ReferenceError: f1 is not defined ?f2(); ??var f1 = function(){}; ?function f2(){}})();
上面代码中函数声明f2被提升,所以在前面调用f2是没问题的。虽然变量f1也被提升,但f1提升后的值为undefined,其真正的初始值是在执行到函数表达式处被赋予的。所以只有声明是被提升的。
深入理解JS中的变量及变量作用域
原文地址:https://www.cnblogs.com/jiayuexuan/p/9263372.html