作用域

作用域是指程序源代码中定义变量的区域。

作用域规定了如何查找变量,也就是确定当前执行代码对变量的访问权限。

JavaScript 采用词法作用域(lexical scoping),也就是静态作用域。

静态作用域与动态作用域

因为 JavaScript 采用的是词法作用域,函数的作用域在函数定义的时候就决定了。

而与词法作用域相对的是动态作用域,函数的作用域是在函数调用的时候才决定的。

让我们认真看个例子就能明白之间的区别:

var value = 1;

function foo() {
console.log(value);
} function bar() {
var value = 2;
foo();
} bar(); // 结果是 ???

假设JavaScript采用静态作用域,让我们分析下执行过程:

执行 foo 函数,先从 foo 函数内部查找是否有局部变量 value,如果没有,就根据书写的位置,查找上面一层的代码,也就是 value 等于 1,所以结果会打印 1。

假设JavaScript采用动态作用域,让我们分析下执行过程:

执行 foo 函数,依然是从 foo 函数内部查找是否有局部变量 value。如果没有,就从调用函数的作用域,也就是 bar 函数内部查找 value 变量,所以结果会打印 2。

前面我们已经说了,JavaScript采用的是静态作用域,所以这个例子的结果是 1。

动态作用域

也许你会好奇什么语言是动态作用域?

bash 就是动态作用域,不信的话,把下面的脚本存成例如 scope.bash,然后进入相应的目录,用命令行执行 bash ./scope.bash,看看打印的值是多少。

value=1
function foo () {
echo $value;
}
function bar () {
local value=2;
foo;
}
bar

这个文件也可以在 Github 博客仓库中找到。

思考题

最后,让我们看一个《JavaScript权威指南》中的例子:

var scope = "global scope";
function checkscope(){
var scope = "local scope";
function f(){
return scope;
}
return f();
}
checkscope();
var scope = "global scope";
function checkscope(){
var scope = "local scope";
function f(){
return scope;
}
return f;
}
checkscope()();

猜猜两段代码各自的执行结果是多少?

这里直接告诉大家结果,两段代码都会打印:local scope

原因也很简单,因为JavaScript采用的是词法作用域,函数的作用域基于函数创建的位置。

而引用《JavaScript权威指南》的回答就是:

JavaScript 函数的执行用到了作用域链,这个作用域链是在函数定义的时候创建的。嵌套的函数 f() 定义在这个作用域链里,其中的变量 scope 一定是局部变量,不管何时何地执行函数 f(),这种绑定在执行 f() 时依然有效。

但是在这里真正想让大家思考的是:

虽然两段代码执行的结果一样,但是两段代码究竟有哪些不同呢?

如果要回答这个问题,就要牵涉到很多的内容,词法作用域只是其中的一小部分,让我们期待下一篇文章————《JavaScript深入之执行上下文栈》。

原文:https://www.cnblogs.com/guaidianqiao/p/7762070.html

最新文章

  1. 解析ASP.NET Mvc开发之EF延迟加载
  2. 转:对于linux下system()函数的深度理解(整理)
  3. SQL Server 添加一条数据获取自动增长列的几种方法
  4. 《算法4》读书笔记 1.4 - 算法分析(Analysis of Algorithm)
  5. Array.from()
  6. myeclipse不编译
  7. C# 如何创建Excel多级分组
  8. css 积累
  9. 3.27模拟赛 sutoringu(后缀数组)
  10. Windows下使用CMD命令进入和退出MySQL数据库
  11. java初始重点语法
  12. 用户名、密码等15个常用的js正则表达式
  13. 富文本编辑器 CKeditor 配置使用
  14. java实现WC项目
  15. POJ 1239 Increasing Sequences 动态规划
  16. IXWebHosting主机如何退款中文图解教程
  17. Cinderella
  18. css总结——position
  19. [ARC 066] Tutorial
  20. 测试UTC时间可以用的网址

热门文章

  1. nuxtjs踩坑指南
  2. android shape图形优化Button效果
  3. POJ 3252 (数位DP)
  4. pixijs shader教程
  5. Type Erasure with Pokemon---swift的类型擦除
  6. [笔记] NuGet Warning NU5100 处理
  7. linux 如何指定nologin用户执行命令
  8. 利用Java EE里jsp制作登录界面
  9. Java学习——包装类
  10. Lucene为什么要加Segment概念