详解JavaScript作用域、作用域链和闭包的用法


Posted in Javascript onSeptember 03, 2020

1. 作用域

作用域是指可访问的变量和函数的集合。

作用域可分为全局作用域和局部作用域。

1.1 全局作用域

全局作用域是指最外层函数外面定义的变量和函数的集合。

换言之,这些最外层函数外面定义的变量和函数在任何地方都能访问。

举个例子:

// 最外层定义变量
var a = 1;

console.log(a); // 最外层可以访问

function fnOne() { // 最外层函数
  
  console.log(a); // 函数内可以访问
  
  function fnTwo() { // 子函数
    console.log(a); // 子函数内也可以访问
  }
}



// 说明
在最外面定义一个变量,不仅在最外面可以访问,
在函数内也能访问,在函数的子函数内也能访问。

1.2 局部作用域

局部作用域是指在函数内部定义的变量和函数的集合。

换言之,这些在函数内部定义的变量和函数,在函数外面是无法访问的,只能在函数内部(包括函数的子孙函数)访问。

举个例子:

function fnThree() {
  // 在函数内定义变量
  var b = 2;
  
  console.log(b); // 函数内部可以访问
  
  function fnFour() {
    console.log(b); // 子函数内也能访问
  }
}
// 函数外不能访问
//console.log(b); 


// 说明
在函数 fnThree 中定义一个变量 b ,在函数内可以访问,
在子函数 fnFour 中也能访问,但在 函数 fnThree 外是不能访问的。

2. 作用域链

从上面的两个例子可以看出,最里层的子函数不仅可以访问最外层函数内的变量,还能访问最外层函数外的全局变量。

这是因为,在创建最外层函数的时候,会把全局作用域拿过来,然后在创建子函数时候,又会把最外层的作用域(包括全局作用域)拿过来,就这样一环扣一环,就形成了作用域链。

所以,作用域链是指内层函数拥有外层函数到最外层(最外层函数外,全局)的所有作用域列表。

3. 闭包

闭包就是能够读取其他函数内部变量的函数。(——百度百科)

从上面的第二个例子可知,函数外是不能访问函数内部定义的局部变量,但是闭包提供了可能。

举个例子:

function User() {
	// 定义私有变量
	var userName = "default";
	
	// 提供 setUserName() 方法
	function setUserName(uName) {
		userName = uName;
	}
	
	// 提供 getUserName() 方法
	function getUserName() {
		return userName;
	}
	
	// 将方法对外开放
	return {
		set: setUserName,
		get: getUserName
	}
}

var user1 = User();
user1.set('tom');
console.log(user1.get());
var user2 = User();
user2.set('jack');
console.log(user2.get());

// 说明
User 函数内部定义变量 uesrName ,
并在内部定义两个子函数操作 userName,
最后将两个子函数返回(一个可直接放回,多个可放到对象中返回。)。

这样,在函数外面可以调用子函数访问函数内部的变量,
这两个子函数便实现了闭包的功能。

以上就是详解JavaScript作用域、作用域链和闭包的用法的详细内容,更多关于JavaScript作用域、作用域链和闭包的资料请关注三水点靠木其它相关文章!

Javascript 相关文章推荐
一个JS的日期格式化算法示例
Jul 31 Javascript
Javascript倒计时页面跳转实例小结
Sep 11 Javascript
jQuery 判断图片是否加载完成方法汇总
Aug 10 Javascript
JS实现浏览器状态栏显示时间的方法
Oct 27 Javascript
Javascript中return的使用与闭包详解
Jan 11 Javascript
详解javascript立即执行函数表达式IIFE
Feb 13 Javascript
Vue按需加载的具体实现
Dec 02 Javascript
webpack分离css单独打包的方法
Jun 12 Javascript
原生JS实现的简单小钟表功能示例
Aug 30 Javascript
详解如何在Vue项目中发送jsonp请求
Oct 25 Javascript
JQuery样式与属性设置方法分析
Dec 07 jQuery
GitHub上77.9K的Axios项目有哪些值得借鉴的地方详析
Jun 15 Javascript
JS变量提升及函数提升实例解析
Sep 03 #Javascript
Vue自定义组件双向绑定实现原理及方法详解
Sep 03 #Javascript
Vue js with语句原理及用法解析
Sep 03 #Javascript
Vue通过provide inject实现组件通信
Sep 03 #Javascript
Vue组件通信$attrs、$listeners实现原理解析
Sep 03 #Javascript
Vue父组件监听子组件生命周期
Sep 03 #Javascript
JavaScript 几种循环方式以及模块化的总结
Sep 03 #Javascript
You might like
openPNE常用方法分享
2011/11/29 PHP
解析php二分法查找数组是否包含某一元素
2013/05/23 PHP
PHP文件上传判断file是否己选择上传文件的方法
2014/11/10 PHP
PHP结合jQuery实现找回密码
2015/07/22 PHP
PHP中模糊查询并关联三个select框
2017/06/19 PHP
一个可以显示阴历的JS代码
2007/03/05 Javascript
浏览器无法运行JAVA脚本的解决方法
2008/01/09 Javascript
关于jquery append() html时的小问题的解决方法
2010/12/16 Javascript
jQuery实现带滑动条的菜单效果代码
2015/08/26 Javascript
jquery实现LED广告牌旋转系统图片切换效果代码分享
2015/08/26 Javascript
Javascript中replace()小结
2015/09/30 Javascript
vue父子组件的嵌套的示例代码
2017/09/08 Javascript
深入理解vue-class-component源码阅读
2019/02/18 Javascript
小程序组件传值和引入sass的方法(使用vant Weapp组件库)
2020/11/24 Javascript
[04:37]DOTA2英雄梦之声Vol20发条
2014/06/20 DOTA
[15:15]教你分分钟做大人:狙击手
2014/10/30 DOTA
详解Python中find()方法的使用
2015/05/18 Python
Python定时执行之Timer用法示例
2015/05/27 Python
python 开发的三种运行模式详细介绍
2017/01/18 Python
Python 中字符串拼接的多种方法
2018/07/30 Python
Matplotlib中文乱码的3种解决方案
2018/11/15 Python
Python中使用双下划线防止类属性被覆盖问题
2019/06/27 Python
python pandas生成时间列表
2019/06/29 Python
python中从for循环延申到推导式的具体使用
2019/11/29 Python
tensorflow入门:tfrecord 和tf.data.TFRecordDataset的使用
2020/01/20 Python
阿波罗盒子:Apollo Box
2017/08/14 全球购物
英国领先的维生素和补充剂品牌:Higher Nature
2019/08/26 全球购物
旅行社各个岗位职责
2014/03/15 职场文书
法律七进实施方案
2014/03/15 职场文书
电视购物广告词
2014/03/19 职场文书
代办委托书怎么写
2014/08/01 职场文书
民警个人对照检查剖析材料
2014/09/17 职场文书
群众路线表态发言材料
2014/10/17 职场文书
2014年个人年终总结
2015/03/09 职场文书
会计求职自荐信
2015/03/26 职场文书
python plt.plot bar 如何设置绘图尺寸大小
2021/06/01 Python