关于JavaScript的作用域,最近听到一个名词:“词法作用域”;以前没有听说过(读书少),记录一下对此的理解,加深印象。

词法作用域:在JavaScript中,一个函数的作用域,在这个函数定义好的时候就决定好了;因此判断该函数的上一级作用域,不是看函数在哪里调用,而是看函数在哪里编写;请勿和this进行混淆了

第1个例子:

1 function fn(callback){
2     var age=18;
3     callback()
4 }
5
6 fn(function(){
7    console.log(age)  // 此处会输出什么结果?
8 })

分析:在第3行代码调用匿名函数时,会在匿名函数的作用域范围内查找age变量,此时的作用域是找不到age变量的;所以会查找匿名函数的上一级,重点是该匿名函数的上一级作用域是什么?好,下面在看一个例子。

第2个例子:

 1 function fn(cb){
 2     var age=18;
 3     cb()
 4 }
 5
 6 function callback(){
 7    console.log(age)  // 此处会输出什么结果?
 8 }
 9
10 fn(callback);

分析:第二个例子相对于第一个列子来说,只是把匿名函数改成了callback函数而已。由第二个例子可以很明确的看出,callback函数的上一级作用域其实是全局作用域,即是window;在callback函数的作用域内,找不到age变量;因此需要网上一级查找,在全局作用域window中也找不到age变量,所以,以上两个例子的输出结果都是报以下的错误:

总结:由上面的两个例子可以看出,在JavaScript中,判断一个函数的上一级作用域是什么?需要看这个函数时在哪个作用域中声明的,而不是在哪个作用域调用的;这就是JavaScript的词法作用域。

 第3个例子:

1 var x = "globol value";
2 function getValue(){
3     console.log(x); // 此处会输出什么?
4     var x = "local value";
5     console.log(x); // 此处会出输出什么?
6 }
7 getValue(); 

分析:按照前面两个例子的词法作用域进行分析,getValue函数是在全局作用域window中编写的,所以是可以访问到window作用域的x变量的,按理来说,输出的结果应该会是:“globol value”和“local value”的;但是,在ES6之前,使用var声明的变量,会存在变量提升即将变量声明提升到它所在作用域的最开始的部分,类似于函数声明提升( function declaration hoisting);因此第3个例子可以改写为如下代码:

1 var x = "globol value";
2 function getValue(){
3     var x; // 声明变量,不进行赋值,默认值为undefined
4     console.log(x);
5     x = "local value";
6     console.log(x);
7 }
8 getValue(); 

所以,第3个例子输出的结果是:undefined和“local value”;如果想要输出“globol value”和“local value”,那么可以改为如下代码:

1 var x = "globol value";
2 function getValue(){
3     console.log(window.x);
4     var x = "local value";
5     console.log(x);
6 }
7 getValue(); 

PS:在ES6中,如果使用let和const关键字来声明变量,是不会存在变量提升的效果的。有兴趣的朋友可以执行一下以下的代码,看看是什么效果,要理解下面这个例子的结果,可以去看看阮一峰老师的关于let的暂时性死区的阐述:http://es6.ruanyifeng.com/#docs/let

1 var x = "globol value";
2 function getValue(){
3     console.log(x);
4     let x = "local value";
5     console.log(x);
6 }
7 getValue();

转载于:https://www.cnblogs.com/llcdxh/p/9335438.html

关于JavaScript的词法作用域及变量提升的个人理解相关推荐

  1. JavaScript之词法作用域和动态作用域

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

  2. js变量作用域和变量提升

    在javascript中, 理解变量的作用域以及变量提升是非常有必要的.这个看起来是否很简单,但其实并不是你想的那样,还要一些重要的细节你需要理解. 变量作用域 "一个变量的作用域表示这个变 ...

  3. JavaScript中的预解析(变量提升)介绍!

    今天小千为大家介绍一下JavaScript中的预解析(变量提升).从什么是预解析及变量的预解析和函数的预解析及加载流程进行学习(注意:我们这里说的ES5中的预解析). 什么是解析 首先代码执行肯定需要 ...

  4. JavaScript 作用域、变量提升

    JavaScript 作用域 JavaScript 作用域 JavaScript 局部作用域 JavaScript 全局变量 JavaScript 变量生命周期 函数参数 HTML 中的全局变量 ES ...

  5. 你不知道的JavaScript之词法作用域

    词法作用域 总结一下作用域的定义:作用域就是一套规则,这套规则用于引擎如何进行查找变量以及在哪找到变量(可以看看之前我博客写的引擎和作用域之间的对话). 作用域分为词法作用域(也叫静态作用域)和动态作 ...

  6. JS 作用域与变量提升---JS 学习笔记(三)

    你知道下面的JavaScript代码执行时会输出什么吗? var foo = 1; function bar() {if (!foo) {var foo = 10;}console.log(foo); ...

  7. JavaScript通俗易懂(一)-变量提升

    原文链接:http://www.jianshu.com/p/330b1505e41d 在JavaScript中,我们肯定不可避免的需要声明变量和函数,可是JS解析器是如何找到这些变量的呢?我们还得对执 ...

  8. JavaScript专题(一)变量提升与预编译,一起去发现Js华丽的暗箱操作

    JavaScript之变量与函数提升 相信阅读完<前端进阶系列>的朋友们已经对Js中经典的知识点有所了解.本系列的第一篇选择了一个值得讨论的问题--变量提升,我们会从遇到问题.分析问题.解 ...

  9. javascript的词法作用域

    这个概念是js中相当基础也是极为重要的,很多想当然的错误或感觉怪异的问题都是和这个东西有关.所以,本文主要说下这个名词的概念以及讨论下他牵扯出来的有关变量.函数.闭包的问题. 由变量开始谈 习惯性先来 ...

最新文章

  1. vendor自动恢复_解决 vendor 中存在大小写变更问题
  2. ThinkPad T61安装Ubuntu9.10全记录
  3. react native 原生模块桥接的简单说明
  4. 开机出现grub界面(待尝试)
  5. linux文件编程(1)—— open、write、read、lseek、阻塞问题
  6. F. It‘s a bird! No, it‘s a plane! No, it‘s AaParsa!
  7. JavaScript 判断浏览器类型
  8. leetcode 8: 字符串转整数(atoi)
  9. 艾伟也谈项目管理,我是如何带领团队开发项目的
  10. (111)FPGA面试题-介绍Verilog 块语句fork-join执行过程
  11. 安全测试-Drozer安全测试框架实践记录篇
  12. 微波雷达感应开关,雷达感应智能模块,照明节能环保技术应用
  13. AT070TN83调试总结(时序)
  14. acm快速输入法 有效解决超时
  15. Groq:从头设计一个张量流式处理器架构
  16. 莫列波纹(Moiré pattern)与Banding
  17. 使用ansible批量修改主机名后/etc/hosts文件不能被正确修改的修复方法
  18. r710服务器系统故障排除,DELL R710服务器安装windows sever2008 故障排除经历(一)硬件排错...
  19. torch当中的MseLoss的reduction参数
  20. 第三部分:成交动力学之十大成交激素——8、稀缺性

热门文章

  1. php 取消命名空间,到PHP命名空间或不到PHP命名空间
  2. android imageview 事件传递,Android 事件传递机制TextView,ImageView等没有默认clickable属性的View单独设置onTouch事件注意事项...
  3. flask连接mysql数据库_Flask与Mysql数据库建立连接
  4. python︱微服务Sanic制作一个简易本地restful API
  5. Promise 的 9 个提示
  6. MyBatis学习(七)
  7. 一行命令获取当前JVM所有可设置的参数以及当前默认值
  8. linux 远程脚本批量 scopy文件
  9. windows下检測文件改变
  10. Lucene中的一些基本概念