详解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 相关文章推荐
jQuery ctrl+Enter shift+Enter实现代码
Feb 07 Javascript
基于Jquery的简单&简陋Tabs插件代码
Feb 09 Javascript
jquery统计复选框选中示例
Nov 05 Javascript
js防止DIV布局滚动时闪动的解决方法
Oct 30 Javascript
JQuery实现防止退格键返回的方法
Feb 12 Javascript
Angularjs 双向绑定时字符串的转换成数字类型的问题
Jun 12 Javascript
使用JS模拟锚点跳转的实例
Feb 01 Javascript
微信小程序实现手指触摸画板
Jul 09 Javascript
vue插件draggable实现拖拽移动图片顺序
Dec 01 Javascript
微信小程序拖拽排序列表的示例代码
Jul 08 Javascript
80行代码写一个Webpack插件并发布到npm
May 24 Javascript
AngularJS实现多级下拉框
Mar 25 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
教你识别简单的免查杀PHP后门
2015/09/13 PHP
PHP设计模式之注册树模式分析
2018/01/26 PHP
对象的类型:本地对象(1)
2006/12/29 Javascript
jquery判断浏览器类型的代码
2012/11/05 Javascript
js调用webservice中的方法实现思路及代码
2013/02/25 Javascript
Json序列化和反序列化方法解析
2013/12/19 Javascript
javascript学习笔记(五)原型和原型链详解
2014/10/08 Javascript
js实现的二级横向菜单条实例
2015/08/22 Javascript
jQuery实现带分组数据的Table表头排序实例分析
2015/11/24 Javascript
JavaScript+html5 canvas实现图片破碎重组动画特效
2016/02/22 Javascript
jQuery表单事件实例代码分享
2016/08/18 Javascript
jQuery操作DOM_动力节点Java学院整理
2017/07/04 jQuery
vue.js移动端app实战1:初始配置详解
2017/07/24 Javascript
Three.js基础学习之场景对象
2017/09/27 Javascript
详解vue+css3做交互特效的方法
2017/11/20 Javascript
bootstrap表格内容过长时用省略号表示的解决方法
2017/11/21 Javascript
JS/jQuery实现获取时间的方法及常用类完整示例
2019/03/07 jQuery
jQuery Migrate 插件用法实例详解
2019/05/22 jQuery
解析原来浏览器原生支持JS Base64编码解码
2019/08/12 Javascript
Vue双向绑定实现原理与方法详解
2020/05/07 Javascript
[47:04]LGD vs infamous Supermajor小组赛D组 BO3 第二场 6.3
2018/06/04 DOTA
Python实现判断字符串中包含某个字符的判断函数示例
2018/01/08 Python
关于tf.reverse_sequence()简述
2020/01/20 Python
python 爬取免费简历模板网站的示例
2020/09/27 Python
Python中openpyxl实现vlookup函数的实例
2020/10/28 Python
垃圾回收的优点和原理
2014/05/16 面试题
乌鸦喝水教学反思
2014/02/07 职场文书
职业培训师职业生涯规划
2014/02/18 职场文书
标准的毕业生自荐信
2014/04/20 职场文书
员工保密承诺书
2014/05/28 职场文书
坚守艰苦奋斗精神坚决反对享乐主义整改措施
2014/09/17 职场文书
志愿者事迹材料
2014/12/26 职场文书
房产公证书格式
2015/01/26 职场文书
《去年的树》教学反思
2016/02/18 职场文书
Python编程super应用场景及示例解析
2021/10/05 Python
PHP RabbitMQ消息列队
2022/05/11 PHP