作用域

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

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

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. POJ2976Dropping tests(分数规划)

    传送门 题目大意:n个二元组a[i],b[i],去掉k个,求sigma a[i]/ sigma b[i]的最大值 代码: #include<iostream> #include<cs ...

  2. Oracle索引知识学习笔记

    目录 一.Oracle索引简介 1.1 索引分类 1.2 索引数据结构 1.3 索引特性 1.4 索引使用注意要点 1.5.索引的缺点 1.6.索引失效 二.索引分类介绍 2.1.位图索引 1.2.函 ...

  3. Ubuntu 16.04上anaconda安装和使用教程,安装jupyter扩展等 | anaconda tutorial on ubuntu 16.04

    本文首发于个人博客https://kezunlin.me/post/23014ca5/,欢迎阅读最新内容! anaconda tutorial on ubuntu 16.04 Guide versio ...

  4. vue.js过度&动画、混入&插件

    1.vue  过度动画 1.过度 Vue 在插入.更新或者移除 DOM 时,提供多种不同方式的应用过渡效果.Vue 提供了内置的过渡封装组件,该组件用于包裹要实现过渡效果的组件. 语法格式: < ...

  5. 一个动态构建 LambdaExpression Tree 的示例

    直接贴代码了: public class ExpressionTreeBuildingSampleTwo : Sample { public override string Name { get; } ...

  6. generator的本质是将异步的管理剥离

    generator的本质是将异步的管理剥离

  7. F#周报2019年第22期

    新闻 2019年实用F#挑战结果 FSharp.Formatting正在确定维护者 实用F#挑战的赢家们 使用F#在分布式系统中进行故障检测与共识 F#里的Cloudflare Worker Juni ...

  8. windows 安装gitea

    gitea 地址https://github.com/go-gitea/gitea windows 安装 

  9. Winforn中使用FastReport实现点击导出按钮PDF预览并弹出另存为对话框

    场景 FastReport安装包下载.安装.去除使用限制以及工具箱中添加控件: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/10 ...

  10. JavaScript HTML DOM 节点

    要向HTML DOM添加新元素,必须首先创建元素(元素节点),然后将其附加到现有元素. <!DOCTYPE html> <html> <meta charset=&quo ...