作用域

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

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

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

【作用域】词法作用域(静态作用域,如:js)、动态作用域(如:.bash脚本)的更多相关文章

  1. 深入学习js之——词法作用域和动态作用域

    开篇 当我们在开始学习任何一门语言的时候,都会接触到变量的概念,变量的出现其实是为了解决一个问题,为的是存储某些值,进而,存储某些值的目的是为了在之后对这个值进行访问或者修改,正是这种存储和访问变量的 ...

  2. 词法作用域 vs 动态作用域

    词法作用域 vs 动态作用域 链接:https://www.jianshu.com/p/cdebb5965000 scheme是一门采用词法作用域(lexical scoping)的lisp方言,这个 ...

  3. 动态作用域与this +apply和call +bind

    词法作用域是一套关于引擎如何寻找变量以及会在何处找到变量的规则. (函数作用域和块作用域) JavaScript 中的作用域就是词法作用域,也就是静态作用域,由定义代码决定 动态作用域似乎暗示有很好的 ...

  4. 区分词法作用域(js)与动态作用域(精!)

    在js学习中,词法作用域是必须要掌握的! 在这里,我将总结一下<你不知道的JS>一书中词法作用域的重点并分享给大家! 首先带来一段代码示例: function foo(){ console ...

  5. js之词法作用域与动态作用域

    事实上JavaScript并不具有动态作用域,它只有词法作用域,简单明了,但是this机制某种程度上很像动态作用域 词法作用域:是一套引擎如何寻找变量以及会在何处找到变量的规则,它是定义在词法阶段的作 ...

  6. JavaScript 词法、静态、动态作用域初级理解

    开始之前 由于本人也是JavaScript初学者,记录学习经过,怕以后会忘记. 对于JavaScript 初学者来说,最难的不是代码部分,而是对很多书籍中的术语的理解,大多时候想要理解一段JavaSc ...

  7. 你不知道的JS之作用域和闭包(二)词法作用域

    原文:你不知道的js系列 词法作用域(Lexical Scope) Lex time 一个标准的编译器的第一个阶段就是分词(token化) 词法作用域就是在词法分析时定义的作用域.换句话说,词法作用域 ...

  8. JavaScript深入之词法作用域和动态作用域

    作用域 作用域是指程序源代码中定义变量的区域. 作用域规定了如何查找变量,也就是确定当前执行代码对变量的访问权限. JavaScript 采用词法作用域,也就是静态作用域. 静态作用域与动态作用域 因 ...

  9. Javascript中的词法作用域、动态作用域、函数作用域和块作用域(四)

    一.js中的词法作用域和动态作用域      词法作用域也就是在词法阶段定义的作用域,也就是说词法作用域在代码书写时就已经确定了.       js中其实只有词法作用域,并没有动态作用域,this的执 ...

随机推荐

  1. python-文件操作&模块&面向对象

    python 文件处理 li = [[']] for i in li: print(','.join(i)) # join字符串拼接 语文,数学,英语 100,122,123 从原文件末尾开始写入 # ...

  2. NOIP201310华容道

    题目描述 Description 小 B 最近迷上了华容道,可是他总是要花很长的时间才能完成一次.于是,他想到用编程来完成华容道:给定一种局面, 华容道是否根本就无法完成,如果能完成, 最少需要多少时 ...

  3. 认识一下transition

    transition 以前的CSS属性切换时,由于只有开始和截止两个状态,切换时略显生硬 jquery.animate 传说中的jquery在保证兼容性之后,又为开发者提供了简洁的过渡(动画其中之一效 ...

  4. mac pe简单安装方法

    1.工具下载 TechTool Pro for mac V11.0.4:http://www.pc6.com/mac/112462.html 2.准备16g u盘 3.安装工具并按照注册码注册 在Te ...

  5. 响应国家号召 1+X 证书 Web 前端开发考试模拟题

    1+x证书Web前端开发初级理论考试样题2019 http://blog.zh66.club/index.php/archives/149/ 1+x证书Web前端开发初级实操考试样题2019 http ...

  6. idea中的后缀补全

    IDEA有个很牛逼的功能,那就是后缀补全(Postfix Completion),这个功能可以通过后缀来使用代码补全进行模板式地补全语句,如遍历循环语句(for.foreach).使用 String. ...

  7. 你必须知道的EF知识和经验(转)

    注意:以下内容如果没有特别申明,默认使用的EF6.0版本,code first模式. 推荐MiniProfiler插件 工欲善其事,必先利其器. 我们使用EF和在很大程度提高了开发速度,不过随之带来的 ...

  8. 2019-11-23-WPF-使用-RawInput-接收裸数据

    原文:2019-11-23-WPF-使用-RawInput-接收裸数据 title author date CreateTime categories WPF 使用 RawInput 接收裸数据 li ...

  9. Delphi - 操作Excel数据公式的实现

    procedure TF_SMP_FT_NEW.RzBitBtn_StartToChangeClick(Sender: TObject); var i, j, ni, nj, iRows, iCol, ...

  10. Kafka Network层解析,还是有人把它说清楚了

    我们知道kafka是基于TCP连接的.其并没有像很多中间件使用netty作为TCP服务器.而是自己基于Java NIO写了一套. 几个重要类 先看下Kafka Client的网络层架构. 本文主要分析 ...