1、js中不存在块级作用域,只存在函数级作用域
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <script> function func(){ for(var i=0;i<10;i++){ } console.log(i); } </script> </body> </html> 这个结果等于10
二、 一个函数就是一个作用域,函数里面的变量如果被声明(创建),那么在函数内部这个变量的作用域就是适用整个函数。
// 这里的xo能够执行成功的原因xo是属于整个函数的,一个函数就是一个作用域 // 下面的ox就不会执行,原因是ox在函数中没有执行 // function test(){ // if(1==1){ // var xo=123; // }else{ // ox=456; // } // document.write(xo,ox); // }
在js中如果不创建变量直接使用就会报错 在js中如果创建变量但是不赋值,那么该值就为undefined 如果在js中先直接使用,然后再创建或者赋值,那么就相当于执行了创建变量
例子:1、
在JavaScript中如果不创建变量,直接去使用,则报错: console.log(xxoo); // 报错:Uncaught ReferenceError: xxoo is not defined JavaScript中如果创建值而不赋值,则该值为 undefined,如: var xxoo; console.log(xxoo); // 输出:undefined 在函数内如果这么写: function Foo(){ console.log(xo); var xo = 'seven'; } Foo(); // 输出:undefined
上述代码,不报错而是输出 undefined,其原因是:JavaScript的函数在被执行之前,会将其中的变量全部声明,而不赋值。所以,相当于上述实例中,函数在“预编译”时,已经执行了var xo;所以上述代码中输出的是undefined。
例子2、
在JavaScript中每个函数作为一个作用域,在外部无法访问内部作用域中的变量
function Main(){ var innerValue = 'seven'; } Main(); console.log(innerValue); // 报错:Uncaught ReferenceError: innerValue is not defined
三、 在函数里面,如果是嵌套函数,会先执行最外层函数,之后执行最内层函数,但是作用域会是从最内层函数中开始从外部层层寻找,如下面中的i为3,和aa为2
下面的for循环执行生成了三个定时器,之后执行每个定时器中的函数。
(即:内层函数的作用域都会去外层函数的作用域寻找)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <script> // 这里执行for循环,i先自增1,直到10的时候就出来 // 这里:创建了3个定时器,,i的值为3。原因分析: // 这里先执行for循环,但是setInterval里面的函数没有执行,等到for循环完毕之后 // 才会执行里面的函数 function func(){ for(var i=0;i<3;i++){ setInterval(function () { console.log(i) ; },1000) } console.log(i); } func(); var aa=1; function f1(){ console.log(aa); } var aa=2; f1(); </script> </body> </html>
例子2:
function func1(){ //下面的inner当成参数传入,一般地函数只有返回值的方法 for(var i=0;i<3;i++){ function inner() { console.log(i); } setInterval(inner,1000); } } func1()
例子3、
这里的alert显示的就是3,先执行外层函数,再执行内层函数,执行完毕之后,内层函数的作用域就在外部依次寻找
<div id="btn_s"> <input type="button" value="点我1"/> <input type="button" value="点我2"/> <input type="button" value="点我3"/> </div> <script> var btn_s=document.getElementById("btn_s").children; for(var j=0;j<btn_s.length;j++){ var current_input=btn_s[j]; current_input.onclick=function(){ alert(j) }
四、自执行函数的作用域:
但遇到之执行函数的时候就要注意和普通函数的作用域的区别,自执行函数一般都是先执行成为一个值
自执行函数:就是把后面括号中的参数传递到第一个括号函数里面
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <script> // 下面的函数就相当于在内部创建了a (function(a){ //var a console.log(a); })(123) // 下面的打印出来的就是0,1,2 // 原因是之执行函数就相当于一个值,而不是一个函数,这个值的话相当于执行完毕了 function func(){ for(var i=0;i<3;i++){ setInterval((function (arg){ console.log(arg); }(i)),1000); } } // 上面的函数就相当于下面 function func(){ for(var i=0;i<3;i++){ var ret=(function(arg){ console.log(arg); })(i); setInterval(ret,1000); } } func() </script> </body> </html>
五、
1 在函数作用域内 加var定义的变量是局部变量,不加var定义的就成了全局变量 2 作用域都是存在于函数中的 3 定义的时候已经创建作用域链,之后按照作用域链来执行
补充:
JS中的call、apply、bind方法详解 http://blog.csdn.net/hj7jay/article/details/53609329
六、总结
1 javascript中没有块级作用域 2 javascript中采用函数作用域 3 javascript中的每个函数作为一个作用域,如果出现嵌套函数,则就会出现作用域链 4 javascript的作用域链在执行前都已经被创建了 5 声明提前