Javascript 作用域
1:函数在未执行前,内部代码不执行
2: javascript中,变量的作用域是函数。 不是代码块
下面的代码中,在一开始编译的时候,会将代码“执行”一次,这个时候变量i的变量已经经过循环变化为了3。但是function并没有执行。
在执行内部function的时候,会现在内部寻找i,因为function内部没有i,所以开始向上寻找。在外部的func找到i,此时i为3。所以下面的代码, 在执行的时候,会一直打印3。
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 7 8 </head> 9 <body> 10 <script> 11 function func(){ 12 for(var i=0; i<3;i++){ 13 setInterval(function(){ 14 console.log(i) 15 },1000); 16 } 17 } 18 19 20 func(); 21 </script> 22 </body> 23 </html>
样例二:
下面的例子中,将样例1 setinterval的部分,修改为了自执行函数。所以在一开始解释的时候,就会去执行。输出1,2,3
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 7 8 </head> 9 <body> 10 <script> 11 function func(){ 12 for(var i=0; i<3;i++){ 13 setInterval((function(arg){ 14 console.log(arg) 15 })(i),1000); 16 } 17 } 18 19 20 func(); 21 </script> 22 </body> 23 </html>
3:javascript的作用域链。如果有嵌套函数,就会出现嵌套作用域链条。
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 </head> 7 <body> 8 <script> 9 xo = 'alex'; 10 11 function Func(){ 12 var xo = "seven"; 13 function inner(){ 14 var xo = 'alvin'; 15 console.log(xo); 16 } 17 inner(); 18 } 19 Func(); 20 </script> 21 </body> 22 </html>
如上述代码则出现三个作用域组成的作用域链,如果出现作用域链后,那么寻找变量时候就会出现顺序,对于上述实例:
当执行console.log(xo)时,其寻找顺序为根据作用域链从内到外的优先级寻找,如果内层没有就逐步向上找,直到没找到抛出异常。
如果注释掉 alvin,将会打印 seven,如果注释掉seven,将会打印 alex

4:作用域在执行前已经存在
样例一:
JavaScript的作用域在被执行之前已经创建,日后再去执行时只需要按照作用域链去寻找即可。
1 xo = 'alex'; 2 3 function Func(){ 4 var xo = "seven"; 5 function inner(){ 6 7 console.log(xo); 8 } 9 return inner; 10 } 11 12 var ret = Func(); 13 ret(); 14 // 输出结果: seven
上述代码,在函数被调用之前作用域链已经存在:
- 全局作用域 -> Func函数作用域 -> inner函数作用域
当执行【ret();】时,由于其代指的是inner函数,此函数的作用域链在执行之前已经被定义为:全局作用域 -> Func函数作用域 -> inner函数作用域,所以,在执行【ret();】时,会根据已经存在的作用域链去寻找变量。
样例二:
1 xo = 'alex'; 2 3 function Func(){ 4 var xo = "eirc"; 5 function inner(){ 6 7 console.log(xo); 8 } 9 xo = 'seven'; 10 return inner; 11 } 12 13 var ret = Func(); 14 ret(); 15 // 输出结果: seven
上述代码和示例一的目的相同,也是强调在函数被调用之前作用域链已经存在:
- 全局作用域 -> Func函数作用域 -> inner函数作用域
不同的时,在执行【var ret = Func();】时,Func作用域中的xo变量的值已经由 “eric” 被重置为 “seven”,所以之后再执行【ret();】时,就只能找到“seven”。
样例三:
1 <script> 2 xo = 'alex'; 3 function Bar(){ 4 console.log(xo); 5 } 6 7 function Func(){ 8 var xo = "seven"; 9 10 return Bar; 11 } 12 13 var ret = Func(); 14 ret(); 15 // 输出结果: alex 16 </script>
上述代码,在函数被执行之前已经创建了两条作用域链:
- 全局作用域 -> Bar函数作用域
- 全局作用域 -> Func函数作用域
当执行【ret();】时,ret代指的Bar函数,而Bar函数的作用域链已经存在:全局作用域 -> Bar函数作用域,所以,执行时会根据已经存在的作用域链去寻找。
5:提前声明
在JavaScript中如果不创建变量,直接去使用,则报错:
1 console.log(xxoo); 2 // 报错:Uncaught ReferenceError: xxoo is not define
JavaScript中如果创建值而不赋值,则该值为 undefined,如:
1 var xxoo; 2 console.log(xxoo); 3 // 输出:undefined
内如果这么写:
1 function Foo(){ 2 console.log(xo); 3 var xo = 'seven'; 4 } 5 6 Foo(); 7 // 输出:undefined
上述代码,不报错而是输出 undefined,其原因是:JavaScript的函数在被执行之前,会将其中的变量全部声明,而不赋值。所以,相当于上述实例中,函数在“预编译”时,已经执行了var xo;所以上述代码中输出的是undefined。

浙公网安备 33010602011771号