详解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 SELECT单选模拟jQuery.select.js
Nov 12 Javascript
5个javascript的数字格式化函数分享
Dec 07 Javascript
JS函数实现动态添加CSS样式表文件
Dec 15 Javascript
js 窗口抖动示例
Sep 04 Javascript
基于jquery异步传输json数据格式实例代码
Nov 23 Javascript
如何判断出一个js对象是否一个dom对象
Nov 24 Javascript
详解vue 中使用 AJAX获取数据的方法
Jan 18 Javascript
微信小程序中子页面向父页面传值实例详解
Mar 20 Javascript
关于JS与jQuery中的文档加载问题
Aug 22 jQuery
vue-cli项目使用mock数据的方法(借助express)
Apr 15 Javascript
js实现GIF动图分解成多帧图片上传
Oct 24 Javascript
JS动态显示倒计时效果
Dec 12 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 缓存函数代码
2008/08/27 PHP
CodeIgniter中使用Smarty3基本配置
2015/06/29 PHP
php正则去除网页中所有的html,js,css,注释的实现方法
2016/11/03 PHP
jquery中的$(document).ready()与window.onload的区别
2009/11/18 Javascript
如何实现修改密码时密码框显示保存到cookie的密码
2013/12/10 Javascript
比较常见的javascript中定义函数的区别
2015/11/09 Javascript
JS+CSS3实现超炫的散列画廊特效
2016/07/16 Javascript
AngularJS通过$location获取及改变当前页面的URL
2016/09/23 Javascript
NodeJS使用七牛云存储上传文件的方法
2017/07/24 NodeJs
Vue.js仿微信聊天窗口展示组件功能
2017/08/11 Javascript
Vue仿手机qq的实例代码(demo)
2017/09/08 Javascript
zTree jQuery 树插件的使用(实例讲解)
2017/09/25 jQuery
详解Ubuntu安装angular-cli遇到的坑
2018/09/08 Javascript
JS实现简易贪吃蛇游戏
2020/08/24 Javascript
vue 使用vant插件做tabs切换和无限加载功能的实现
2020/11/04 Javascript
[02:10]DOTA2亚洲邀请赛 EG战队出场宣传片
2015/02/07 DOTA
Python中的异常处理学习笔记
2015/01/28 Python
Python的Django应用程序解决AJAX跨域访问问题的方法
2016/05/31 Python
mac安装scrapy并创建项目的实例讲解
2018/06/13 Python
Python定义二叉树及4种遍历方法实例详解
2018/07/05 Python
Django对models里的objects的使用详解
2019/08/17 Python
Python缓存技术实现过程详解
2019/09/25 Python
Python解析多帧dicom数据详解
2020/01/13 Python
Pycharm IDE的安装和使用教程详解
2020/04/30 Python
python3.4中清屏的处理方法
2020/07/06 Python
Django返回HTML文件的实现方法
2020/09/17 Python
python regex库实例用法总结
2021/01/03 Python
HTML5 localStorage使用总结
2017/02/22 HTML / CSS
天美时手表加拿大官网:Timex加拿大
2016/09/01 全球购物
英国领先的男装设计师服装独立零售商:Repertoire Fashion
2020/10/19 全球购物
高中毕业生登记表自我鉴定范文
2014/03/18 职场文书
村委会换届选举方案
2014/05/03 职场文书
2014国庆节演讲稿:祖国在我心中(400字)
2014/09/25 职场文书
工作简历的自我评价
2019/05/16 职场文书
2019最新版试用期劳动合同模板!
2019/07/04 职场文书
商业计划书如何写?关键问题有哪些?
2019/07/11 职场文书