作用域是指变量和函数可访问范围,他规定了如何查找变量,也就是确定当前执行代码对变量的访问权限。
作用域有两种工作模式:
静态作用域 :又称为词法作用域,在编译阶就可以决定变量的引用,由程序定义的位置决定,和代码执行顺序无关,用嵌套的方式解析。
动态作用域 :在程序运行时候,和代码的执行顺序决定,用动态栈动态管理。
JavaScript 采用的是词法作用域,函数的作用域在函数编译时的时候就决定了。
- <script>
- var a = 10;
- function run() {
- console.log(a); //10
- }
- function fo() {
- var a = 20;
- run();
- }
- fo();
- </script>
执行 run函数,先从run 函数内部查找是否有局部变量 a,如果没有,就根据代码书写位置,向上查找变量a,也就是a等于10,所以结果会打印 10。
假设JavaScript采用动态作用域,让我们分析下执行过程:
执行run 函数,依然是从run 函数内部查找是否有局部变量 a。如果没有,就从调用函数的作用域,也就是fo函数内部查找 a变量,所以结果会打印 20。
前面我们已经说了,JavaScript采用的是静态作用域,所以这个例子的结果是 10。
ES5在词法作用域工作模式(一种规则)下又分为全局作用域和函数作用域,没有块作用域(es6以后有)。
全局作用域:该作用域的变量、对象在任何地方都是可见的,变量没有在函数内声明或者声明的时候没有带var就是全局变量,拥有全局作用域,window对象的所有属性拥有全局作用域,在代码任何地方都可以访问。
在客户端javascript 中,表示的浏览器窗口中window对象充当了全局对象,拥有全局作用域。
- <script>
- var a = 10;
- function run() {
- console.log(a); //10
- }
- function fo() {
- var a = 20;
- run();
- }
- fo();
- </script>
- <script>
- console.log(a) //10
- </script>
全局变量a ,在run函数以及第二个<script>代码块中也是可见的;
函数作用域:在函数内声明的变量,那么在函数内及其子函数内都是可见的,在函数外是不可见的。
- function fo(){
- var myName='Joel';
- }
- console.log(myName)//ReferenceError: myName is not defined
块级作用域是指在{...}内的代码块,每一段代码块都有各自的作用域,且声明的变量在代码块外是不可见的 如:
- function run() {
- var a = 10;
- if (true) {
- var b = 10;
- }
- console.log(b); //如果存在块作用域,那么这里打印这个b是会报错的
- }
总结
单纯的作用域还是好理解,javascript的作用域是静态作用域,即应该关心代码的位置而不是调用的位置 如:
- <script>
- var x = 10;
- function fn() {
- console.log(x);
- }
- function show(f) {
- var x = 20; (function() {
- f()
- } ());
- }
- show(fn); //10
- </script>
来源: http://www.cnblogs.com/CandyManPing/p/7744514.html