详解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 相关文章推荐
extjs DataReader、JsonReader、XmlReader的构造方法
Nov 07 Javascript
JavaScript Date对象 日期获取函数
Dec 19 Javascript
Extjs改变树节点的勾选状态点击按钮将复选框去掉
Nov 14 Javascript
JavaScript设计模式之适配器模式介绍
Dec 28 Javascript
jQuery 3.0中存在问题及解决办法
Jul 15 Javascript
js实现颜色阶梯渐变效果(Gradient算法)
Mar 21 Javascript
jQuery幻灯片插件owlcarousel参数说明中文文档
Feb 27 jQuery
Jquery的autocomplete插件用法及参数讲解
Mar 12 jQuery
详解简单易懂的 ES6 Iterators 指南和示例
Sep 24 Javascript
ES6 proxy和reflect的使用方法与应用实例分析
Feb 15 Javascript
基于JavaScript实现十五拼图代码实例
Apr 26 Javascript
JS+JQuery实现无缝连接轮播图
Dec 30 jQuery
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
雄兵连:第三季确定会出,不过时间未定,鹤熙是第三季的主角!
2020/03/13 国漫
PHP表单数据写入MySQL数据库的代码
2016/05/31 PHP
js 目录列举函数
2008/11/06 Javascript
js 禁止选择功能实现代码(兼容IE/Firefox)
2010/04/23 Javascript
解析使用js判断只能输入数字、字母等验证的方法(总结)
2013/05/14 Javascript
推荐4个原生javascript常用的函数
2015/01/12 Javascript
wangEditor编辑器失去焦点后仍然可以在原位置插入图片分析
2015/05/06 Javascript
JS随机调用指定函数的方法
2015/07/01 Javascript
JavaScript动态设置div的样式的方法
2015/12/26 Javascript
js表单验证实例讲解
2016/03/31 Javascript
关于js原型的面试题讲解
2016/09/25 Javascript
jQuery学习笔记之入门
2016/12/14 Javascript
JavaScript中三种常见的排序方法
2017/02/24 Javascript
Angular 4.x 路由快速入门学习
2017/05/03 Javascript
详解angularjs中如何实现控制器和指令之间交互
2017/05/31 Javascript
React组件生命周期详解
2017/07/03 Javascript
详解在vue-cli中使用路由
2017/09/25 Javascript
基于vue的换肤功能的示例代码
2017/10/10 Javascript
vue  自定义组件实现通讯录功能
2018/09/30 Javascript
JS中实现浅拷贝和深拷贝的代码详解
2019/06/05 Javascript
vue 源码解析之虚拟Dom-render
2019/08/26 Javascript
jQuery实现鼠标滑动切换图片
2020/05/27 jQuery
JavaScript实现简易计算器小功能
2020/10/22 Javascript
[03:26]《DAC最前线》之EG经理自述DOTA2经历
2015/02/02 DOTA
Python运行的17个时新手常见错误小结
2012/08/07 Python
Python警察与小偷的实现之一客户端与服务端通信实例
2014/10/09 Python
python变量不能以数字打头详解
2016/07/06 Python
Python多线程应用于自动化测试操作示例
2018/12/06 Python
Python3.5内置模块之time与datetime模块用法实例分析
2019/04/27 Python
python实现本地批量ping多个IP的方法示例
2019/08/07 Python
pytorch获取vgg16-feature层输出的例子
2019/08/20 Python
Python3简单爬虫抓取网页图片代码实例
2019/08/26 Python
解决Python import docx出错DLL load failed的问题
2020/02/13 Python
Matplotlib配色之Colormap详解
2021/01/05 Python
canvas绘图按照contain或者cover方式适配并居中显示
2019/02/18 HTML / CSS
美国时尚假发购物网站:Wigsbuy
2019/04/06 全球购物