详解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下:nth-child(an+b)的使用注意
May 28 Javascript
JQuery获取与设置HTML元素的内容或文本的实现代码
Jun 20 Javascript
JS中产生标识符方式的演变
Jun 12 Javascript
原生js实现模拟滚动条
Jun 15 Javascript
JS获取数组最大值、最小值及长度的方法
Nov 24 Javascript
基于gulp合并压缩Seajs模块的方式说明
Jun 14 Javascript
微信JSAPI支付操作需要注意的细节
Jan 10 Javascript
Vue单文件组件的如何使用方式介绍
Jul 28 Javascript
JavaScript选择排序算法原理与实现方法示例
Aug 06 Javascript
vue 使用鼠标滚动加载数据的例子
Oct 31 Javascript
解决vue-photo-preview 异步图片放大失效的问题
Jul 29 Javascript
JavaScript日期库date-fn.js使用方法解析
Sep 09 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
dede全站URL静态化改造[070414更正]
2007/04/17 PHP
php实现微信支付之退款功能
2018/05/30 PHP
php常用的工具开发整理
2019/09/26 PHP
Laravel Eloquent分表方法并使用模型关联的实现
2019/11/25 PHP
javascript编程起步(第一课)
2007/01/10 Javascript
JavaScript中eval函数的问题
2016/01/31 Javascript
Bootstrap CSS布局之按钮
2016/12/17 Javascript
如何编写jquery插件
2017/03/29 jQuery
前端构建工具之gulp的语法教程
2017/06/12 Javascript
bootstrap可编辑下拉框jquery.editable-select
2017/10/12 jQuery
详解Angular5 路由传参的3种方法
2018/04/28 Javascript
详解创建自定义的Angular Schematics
2018/06/06 Javascript
vue中render函数的使用详解
2018/10/12 Javascript
js实现下拉框二级联动
2018/12/04 Javascript
Vue 中的受控与非受控组件的实现
2018/12/17 Javascript
使用ThinkJs搭建微信中控服务的实现方法
2019/08/08 Javascript
JavaScript实现动态留言板
2020/03/16 Javascript
k8s node节点重新加入master集群的实现
2021/02/22 Javascript
Python中的字符串替换操作示例
2016/06/27 Python
Python 取numpy数组的某几行某几列方法
2019/10/24 Python
python tkinter canvas使用实例
2019/11/04 Python
Python3监控疫情的完整代码
2020/02/20 Python
Python带参数的装饰器运行原理解析
2020/06/09 Python
python 基于selectors库实现文件上传与下载
2020/12/31 Python
Python列表元素删除和remove()方法详解
2021/01/04 Python
Boden美国官网:英伦原创时装品牌
2017/07/03 全球购物
新西兰第一的行李箱网站:luggage.co.nz
2019/07/22 全球购物
中国包裹转运寄送国际服务:Famiboat
2019/07/24 全球购物
2014年社区学雷锋活动总结
2014/03/09 职场文书
货车司机岗位职责
2014/03/18 职场文书
公务员党员评议表自我鉴定
2014/09/14 职场文书
会议营销主持词
2015/07/03 职场文书
新入职员工工作总结
2015/10/15 职场文书
小学班级标语口号大全
2015/12/26 职场文书
如何拟写通知正文?
2019/04/02 职场文书
TV动画「神渣☆爱豆」公开第一弹主视觉图
2022/03/21 日漫