通过函数作用域和块级作用域看javascript的作用域链


Posted in Javascript onAugust 05, 2018

在ES6之前,javascript只有全局作用域和函数作用域。所谓作用域就是一个变量定义并能够被访问到的范围。也就是说如果一个变量定义在全局(window)上,那么在任何地方都能访问到这个变量,如果这个变量定义在函数内部,那么就只能在函数内部访问到这个变量。

全局作用域只要页面没关闭就会一直存在,而函数作用域只有在函数执行的时候才存在,执行完就销毁。且每次执行函数都会创建一个新的作用域。

那么什么是作用域链呢?
在了解作用域链之前,我们先了解一个执行期上下文的概念。

执行期上下文:当函数执行时,会创建一个称为执行期上下文的内部对象(即AO或GO),一个执行期上下文定义了一个函数的执行环境,函数每次执行时对应的执行期上下文都是独一无二的,所以每次调用一个函数都会创建一个新的执行期上下文,当函数执行完毕,所产生的执行期上下文被销毁。

作用域链就是函数中[[scope]]属性所存储的执行期上下文对象的集合,这个集合呈链式链接,我们把这种链式链接叫做作用域链。

作用域链更像是一种包含的关系。比如说函数A内部定义了一个函数B,所以B的定义是依赖于A的,也就是说B在A的内部,那么B中就可以访问A的中的变量和方法。这种一层一层向上依赖的关系就构成了作用域链。

为了更好理解,我们直接看例子。

var name = 'xiaoyu';
function fn1() {};
function fn2() {
 var num = 10;
 function fn3() {
  var num1 = 10;
  console.log(num);
 };
 return fn3;
}
var fn4 = fn2();

通过函数作用域和块级作用域看javascript的作用域链

在上个例子我们知道,fn2执行的时候返回fn3,产生了闭包。但是一个函数执行然后返回另一个函数都会产生闭包嘛?我们来看一下。

var name = 'xiaoyu';
function fn1() {};
function fn2() {
 var num = 10;
 function fn3() {//fn3函数没有依赖fn2函数内的变量
  var num1 = 10;
  console.log(num1);
 };
 return fn3;
}
var fn4 = fn2();

通过函数作用域和块级作用域看javascript的作用域链

了解了作用域链之后,我们来看一个小例子,巩固一下。

var age = 10;
var obj = {
 age: 12,
 test: function() {
  console.log(age);
  console.log(obj.age);
  console.log(this.age);
 }
}
obj.test();

console.log(this.age)打印出12不难理解,但是为什么console.log(age)不也应该打印出12嘛。

我们说test执行时首先会在自己的作用域内查看有没有age变量,然后再沿着作用域链往上到全局作用域查找age变量,全局作用域下有age变量和data变量。所以console.log(age)打印出的10,如果要打印出12则需要访问obj.age。

ES6的块级作用域

在ES6之后,通过let和const引入了块级作用域。即通过let和const声明的变量只在声明所在的块级作用域内有效,并且let声明的变量虽然属于全局变量,但不再属于全局对象window。

我们通过一段代码来看一下引入块级作用域后,函数的作用域链的变化。

var age = 10;
let obj = {
 age: 12,
 test: function() {
   console.log(age);
   console.log(obj.age);
   console.log(this.age);
 }
}
obj.test();

通过函数作用域和块级作用域看javascript的作用域链

Javascript 相关文章推荐
IE中jscript/javascript的条件编译
Sep 07 Javascript
JavaScript开发时的五个注意事项
Dec 08 Javascript
jQuery 对象中的类数组操作
Apr 27 Javascript
kmock javascript 单元测试代码
Feb 06 Javascript
IE下使用cloneNode注意事项分享
Nov 22 Javascript
javascrpt绑定事件之匿名函数无法解除绑定问题
Dec 06 Javascript
JS实现字体选色板实例代码
Nov 20 Javascript
jquery和ajax的关系详细介绍
Nov 29 Javascript
javascript自定义右键弹出菜单实现方法
May 25 Javascript
vue解决一个方法同时发送多个请求的问题
Sep 25 Javascript
vue.js click点击事件获取当前元素对象的操作
Aug 07 Javascript
javascript实现电商放大镜效果
Nov 23 Javascript
vue实现简单的MVVM框架
Aug 05 #Javascript
使用D3.js+Vue实现一个简单的柱形图
Aug 05 #Javascript
详解Require.js与Sea.js的区别
Aug 05 #Javascript
vue中关闭eslint的方法分析
Aug 04 #Javascript
详解Vue取消eslint语法限制
Aug 04 #Javascript
JavaScript原型对象、构造函数和实例对象功能与用法详解
Aug 04 #Javascript
JavaScript中变量、指针和引用功能与操作示例
Aug 04 #Javascript
You might like
smarty模板中使用get、post、request、cookies、session变量的方法
2014/04/24 PHP
PHP使用XMLWriter读写xml文件操作详解
2018/07/31 PHP
PHP框架实现WebSocket在线聊天通讯系统
2019/11/21 PHP
PHP的图像处理实例小结【文字水印、图片水印、压缩图像等】
2019/12/20 PHP
js左侧多级菜单动态的解决方案
2010/02/01 Javascript
javascript文件中引用依赖的js文件的方法
2014/03/17 Javascript
JS 动态加载js文件和css文件 同步/异步的两种简单方式
2016/09/23 Javascript
Javascript中return的使用与闭包详解
2017/01/11 Javascript
vue loadmore 组件滑动加载更多源码解析
2017/07/19 Javascript
react-native-fs实现文件下载、文本存储的示例代码
2017/09/22 Javascript
原生js实现form表单序列化的方法
2018/08/02 Javascript
JS 正则表达式验证密码、邮箱格式的实例代码
2018/10/28 Javascript
vscode下的vue文件格式化问题
2018/11/28 Javascript
JavaScript定时器设置、使用与倒计时案例详解
2019/07/08 Javascript
vue中监听返回键问题
2019/08/28 Javascript
详解vue-router的导航钩子(导航守卫)
2020/11/02 Javascript
vue.js+element 默认提示中英文操作
2020/11/11 Javascript
[03:59]5分钟带你了解什么是DOTA2(第二期)
2017/02/07 DOTA
[42:23]完美世界DOTA2联赛PWL S3 Forest vs Rebirth 第二场 12.10
2020/12/13 DOTA
Python基于二分查找实现求整数平方根的方法
2016/05/12 Python
Python中的异常处理try/except/finally/raise用法分析
2019/02/28 Python
python实现登录密码重置简易操作代码
2019/08/14 Python
python 数据提取及拆分的实现代码
2019/08/26 Python
Python实现把多维数组展开成DataFrame
2019/11/30 Python
python3实现网页版raspberry pi(树莓派)小车控制
2020/02/12 Python
python 判断一组数据是否符合正态分布
2020/09/23 Python
HTML5 通信API 跨域门槛将不再高、数据推送也不再是梦
2013/04/25 HTML / CSS
苹果中国官方网站:Apple中国
2016/07/22 全球购物
应届毕业生求职信范例分享
2013/12/17 职场文书
班级道德讲堂实施方案
2014/02/24 职场文书
党员评议思想汇报
2014/10/08 职场文书
2014年工商所工作总结
2014/12/09 职场文书
2014年干部培训工作总结
2014/12/17 职场文书
公司放假通知范文
2015/04/14 职场文书
涨价通知
2015/04/23 职场文书
django项目、vue项目部署云服务器的详细过程
2022/07/23 Servers