详解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中的变量使用说明
May 18 Javascript
jQuery 一个图片切换的插件
Oct 09 Javascript
jQuery对象的length属性用法实例
Dec 27 Javascript
JavaScript中用字面量创建对象介绍
Dec 31 Javascript
全面了解js中的script标签
Jul 04 Javascript
浅谈JavaScript 覆盖原型以及更改原型
Aug 31 Javascript
lhgcalendar时间插件限制只能选择三个月的实现方法
Jul 03 Javascript
ES6中的rest参数与扩展运算符详解
Jul 18 Javascript
深入浅析var,let,const的异同点
Aug 07 Javascript
javascript中call,apply,callee,caller用法实例分析
Jul 24 Javascript
JavaScript对象原型链原理详解
Feb 05 Javascript
详解Vue的mixin策略
Nov 19 Vue.js
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无限分类的深入理解
2013/06/02 PHP
destoon调用discuz论坛中带图片帖子的实现方法
2014/08/21 PHP
Fedora下安装php Redis扩展笔记
2014/09/03 PHP
PHP实现的多文件上传类及用法示例
2016/05/06 PHP
PHP实现在对象之外访问其私有属性private及保护属性protected的方法
2017/11/20 PHP
php如何把表单内容提交到数据库
2019/07/08 PHP
枚举JavaScript对象的函数
2006/12/22 Javascript
PHP和NodeJs开发的应用如何共用Session
2015/04/16 NodeJs
谈谈AngularJs中的隐藏和显示
2015/12/09 Javascript
js css+html实现简单的日历
2016/07/14 Javascript
JavaScript实现点击按钮复制指定区域文本(推荐)
2016/11/25 Javascript
JavaScript 保护变量不被随意修改的实现代码
2017/09/27 Javascript
js实现input密码框显示/隐藏功能
2020/09/10 Javascript
如何让node运行es6模块文件及其原理详解
2018/12/11 Javascript
JS实现带阴历的日历功能详解
2019/01/24 Javascript
Python isinstance判断对象类型
2008/09/06 Python
Python实现简易端口扫描器代码实例
2017/03/15 Python
django中的HTML控件及参数传递方法
2018/03/20 Python
Python中的枚举类型示例介绍
2019/01/09 Python
python使用pipeline批量读写redis的方法
2019/02/18 Python
Python使用reportlab模块生成PDF格式的文档
2019/03/11 Python
python获取点击的坐标画图形的方法
2019/07/09 Python
Flask框架学习笔记之路由和反向路由详解【图文与实例】
2019/08/12 Python
浅析PyTorch中nn.Module的使用
2019/08/18 Python
解决pycharm下pyuic工具使用的问题
2020/04/08 Python
python实现IOU计算案例
2020/04/12 Python
opencv python 图片读取与显示图片窗口未响应问题的解决
2020/04/24 Python
python中adb有什么功能
2020/06/07 Python
python使用QQ邮箱实现自动发送邮件
2020/06/22 Python
Python里面如何实现tuple和list的转换
2012/06/13 面试题
四议两公开实施方案
2014/03/28 职场文书
《春笋》教学反思
2014/04/15 职场文书
十佳好少年事迹材料
2014/08/21 职场文书
员工培训协议书
2014/09/15 职场文书
奔腾年代观后感
2015/06/09 职场文书
高一作文之暖冬
2019/11/09 职场文书