详解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 相关文章推荐
javascript 处理事件绑定的一些兼容写法
Dec 24 Javascript
firefox插件Firebug的使用教程
Jan 02 Javascript
疯狂Jquery第一天(Jquery学习笔记)
May 11 Javascript
原生JS实现LOADING效果
Mar 16 Javascript
JavaScript实现的浮动层框架用法实例分析
Oct 10 Javascript
详解JavaScript中this关键字的用法
May 26 Javascript
js实现table添加行tr、删除行tr、清空行tr的简单实例
Oct 15 Javascript
JS正则替换去空格的方法
Mar 24 Javascript
js实现鼠标拖拽多选功能示例
Aug 01 Javascript
详解如何在项目中使用jest测试react native组件
Feb 09 Javascript
微信小程序如何加载数据库真实数据的实现
Mar 04 Javascript
swiper实现导航滚动效果
Dec 13 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和XSS跨站攻击的防范
2007/04/17 PHP
php in_array 函数使用说明与in_array需要注意的地方说明
2010/04/13 PHP
PHP中使用CURL发送get/post请求上传图片批处理功能
2018/10/15 PHP
Laravel 实现Eloquent模型分组查询并返回每个分组的数量 groupBy()
2019/10/23 PHP
JQuery获取元素文档大小、偏移和位置和滚动条位置的方法集合
2010/01/12 Javascript
浅析Js中的单引号与双引号问题
2013/11/06 Javascript
js 阻止子元素响应父元素的onmouseout事件具体实现
2013/12/23 Javascript
JS+CSS实现简易实用的滑动门菜单效果
2015/09/18 Javascript
JS简单实现DIV相对于浏览器固定位置不变的方法
2016/06/17 Javascript
js实现文字超出部分用省略号代替实例代码
2016/09/01 Javascript
vue制作加载更多功能的正确打开方式
2016/10/12 Javascript
扩展Bootstrap Tooltip插件使其可交互的方法
2016/11/07 Javascript
Bootstrap导航条鼠标悬停下拉菜单
2017/01/04 Javascript
简单谈谈原生js的math对象
2017/06/27 Javascript
jQuery表单设置值的方法
2017/06/30 jQuery
vue开发调试神器vue-devtools使用详解
2017/07/13 Javascript
如何给element添加一个抽屉组件的方法步骤
2019/07/14 Javascript
ant design 日期格式化的实现
2020/10/27 Javascript
python3生成随机数实例
2014/10/20 Python
使用py2exe在Windows下将Python程序转为exe文件
2016/03/04 Python
Python实现一个Git日志统计分析的小工具
2017/12/14 Python
spark dataframe 将一列展开,把该列所有值都变成新列的方法
2019/01/29 Python
python实现小球弹跳效果
2019/05/10 Python
Python线程指南分享
2019/11/19 Python
Django使用list对单个或者多个字段求values值实例
2020/03/31 Python
HTML5 实战PHP之Web页面表单设计
2011/10/09 HTML / CSS
Nike墨西哥官网:Nike MX
2020/08/30 全球购物
波兰多品牌运动商店:StreetStyle24.pl
2020/09/22 全球购物
Linux的文件类型
2016/07/05 面试题
编辑硕士自荐信范文
2013/11/27 职场文书
园林系毕业生求职信
2014/06/23 职场文书
2015应届毕业生自荐信范文
2015/03/05 职场文书
就业推荐表院系意见
2015/06/05 职场文书
婚礼领导致辞大全
2015/07/28 职场文书
如何通过一篇文章了解Python中的生成器
2022/04/02 Python
详解Anyscript开发指南绕过typescript类型检查
2022/09/23 Javascript