详解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 表单验证扩展代码(二)
Oct 20 Javascript
基于jQuery的图片不完全按比例自动缩小
Jul 11 Javascript
JQuery实现带排序功能的权限选择实例
May 18 Javascript
js实现文本框输入文字个数限制代码
Dec 25 Javascript
js判断checkbox是否选中个数的方法(超简单)
Aug 19 Javascript
js 轮播效果实例分享
Dec 28 Javascript
JS获取浮动(float)元素的style.left值为空的快速解决办法
Feb 19 Javascript
ES6中Proxy与Reflect实现重载(overload)的方法
Mar 30 Javascript
AngularJS表单验证功能分析
May 26 Javascript
详解vue.js根据不同环境(正式、测试)打包到不同目录
Jul 13 Javascript
JavaScript实现旋转木马轮播图
Mar 16 Javascript
js实现简单音乐播放器
Jun 30 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判断服务器是否是HTTPS连接
2013/07/05 PHP
PHP通过内置函数memory_get_usage()获取内存使用情况
2014/11/20 PHP
PHP使用ajax的post方式下载excel文件简单示例
2019/08/06 PHP
PHP 超级全局变量相关总结
2020/06/30 PHP
javascript下数值型比较难点说明
2010/06/07 Javascript
jquery设置元素的readonly和disabled的写法
2013/09/22 Javascript
JavaScript继承模式粗探
2016/01/12 Javascript
jQuery模拟淘宝购物车功能
2017/02/27 Javascript
nodejs实现大文件(在线视频)的读取
2020/10/16 NodeJs
用node-webkit把web应用打包成桌面应用(windows环境)
2018/02/01 Javascript
JS实现运动缓冲效果的封装函数示例
2018/02/18 Javascript
详解JavaScript中操作符和表达式
2018/09/12 Javascript
使用微信小程序开发弹出框应用实例详解
2018/10/18 Javascript
Vue的生命周期操作示例
2019/09/17 Javascript
解决nuxt页面中mounted、created、watch执行两遍的问题
2020/11/05 Javascript
如何在vue-cli中使用css-loader实现css module
2021/01/07 Vue.js
Django中url的反向查询的方法
2018/03/14 Python
Python实现时钟显示效果思路详解
2018/04/11 Python
让Python脚本暂停执行的几种方法(小结)
2019/07/11 Python
python for循环remove同一个list过程解析
2019/08/14 Python
详解Django-channels 实现WebSocket实例
2019/08/22 Python
pytorch之ImageFolder使用详解
2020/01/06 Python
keras tensorflow 实现在python下多进程运行
2020/02/06 Python
css3一款3D字体带阴影效果的实现步骤
2013/03/20 HTML / CSS
使用phonegap克隆和删除联系人的实现方法
2017/03/31 HTML / CSS
电子专业毕业生自我鉴定
2014/01/22 职场文书
物业总经理岗位职责
2014/02/28 职场文书
计算机网络工程专业职业生涯规划书
2014/03/10 职场文书
《社戏》教学反思
2014/04/15 职场文书
档案保密承诺书
2014/06/03 职场文书
环境监测与治理技术专业求职信
2014/07/06 职场文书
机关党总支领导班子整改方案
2014/09/20 职场文书
学校总务处领导班子民主生活会对照检查材料思想汇报
2014/09/27 职场文书
领导离职感言
2015/08/03 职场文书
导游词之天津古文化街
2019/11/09 职场文书
opencv深入浅出了解机器学习和深度学习
2022/03/17 Python