JavaScript 作用域(Scope)详解
先对需要用到的名词解释一下,再通过例子深入理解
一、什么是作用域(Scope)
[[scope]]:每个javascript函数都是一个对象,对象中有些属性我们可以访问,但有些不可以,这些属性仅供javascript引擎存取,[[scope]]就是其中一个。[[scope]]指的就是我们所说的作用域,其中存储了运行期上下文的集合。即作用域决定了代码区块中变量和其他资源的可见性。
二、变量的作用域类型
1.全局作用域:全局作用域贯穿整个javascript文档,在所有函数声明或者大括号之外定义的变量,都在全局作用域里。一旦你声明了一个全局变量,那么你在任何地方都可以使用它,包括函数内部。
2.局部作用域:局部作用域一般只在固定的代码片段内可访问到,而其外部是无法访问的,它分为函数作用域和块级作用域
a:函数作用域: 当你在函数里定义一个变量时,它在函数内任何地方都可以使用。在函数之外,你就无法访问它了。
b:块级作用域:你在使用大括号时,声明了一个const
或者let
的变量时,你就只能在大括号内部使用这一变量。
三、作用域链
作用域链:[[scope]]中所存储的执行期上下文对象的集合,这个集合呈链式链接,我们把这种链式链接叫做作用域链。
四、执行期上下文
当函数执行时,会创建一个称为执行期上下文的内部对象。一个执行期上下文定义了一个函数执行时的环境,函数每次执行时对应的执行上下文都是独一无二的,所以多次调用一个函数会导致创建多个执行上下文,当函数执行完毕,执行上下文被销毁。(即AO、GO,不了解的可参考预预编译文章)
五、查找变量
在函数中查找变量,从其作用域链的顶端依次向下查找,从Scope chain 的0位依次查到最后一位。
通过一个例子具体了解上面的定义:
<script> function a() { function b() { var bb = 234 } var aa = 123; b(); } var glob = 100; a(); </script>
1.a()定义时,其Scope里存放GO
2.a()执行时,形成作用域链,Scope chain[0] 存放AO, Scope chain[1] 存放GO
3: b()定义,因为它是a()内部的函数,因此其执行期上下文与a()执行时是一样的;
4:b()执行时,产生自己的AO,在作用域链中将a()的AO与GO储存位置下移,第0位存自己的AO
注意:b() Scope chain 储存的a() 的AO与a()中的AO一样,只是将其引用挂到里面,即通过b()中可以改变a()中变量的值
例:
<script> function a() { function b() { var bb = 234 aa = 0; } var aa = 123; b();
console.log(a); } var glob = 100; a(); </script>
输出a的值为 0
- 图论----同构图(详解)
- 基数排序与桶排序,计数排序【详解】
- SG函数和SG定理【详解】
- 密码学经典之生日悖论与生日攻击【详解】
- POJ 1659 Frogs' Neighborhood(可图性判定—Havel-Hakimi定理)【超详解】
- BZOJ 1192: [HNOI2006]鬼谷子的钱袋(新生必做的水题)
- 快速傅里叶变换(FFT)算法【详解】
- Codeforces Round #416 (Div. 2)(A,思维题,暴力,B,思维题,暴力)
- 作为程序员的你在外行人眼里是一个怎样的群体?
- 高斯消元法(Gauss Elimination)【超详解&模板】
- [快学Python3]读写Excel - openpyxl库
- HDU 2147 kiki's game(规律,博弈)
- HDU 1847 Good Luck in CET-4 Everybody!(规律,博弈)
- [network][udp]你不要偷偷发包,我跟你讲
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Python实战之tkinter库画图,用canver画布教你画卡通人物!
- Python教程之正则表达式(基础篇)
- Python教程之正则表达式(提高篇)
- 【剑指Offer】树的子结构
- 【剑指Offer】合并两个排序的链表
- Python实战之特定文本提取,挑战高效办公的第一步
- 【剑指Offer】调整数组顺序使奇数位于偶数前面
- 【剑指Offer】链表中倒数第 k 个节点
- 【剑指Offer】调整数组顺序使奇数位于偶数前面
- 【剑指Offer】复杂链表的复制
- 【剑指Offer】二叉树中和为某一值的路径
- 【剑指Offer】二叉搜索树的后序遍历序列
- 【剑指Offer】Ⅲ. 从上到下打印二叉树
- scRepertoire||单细胞免疫组库分析:R语言应用(二)
- 【剑指Offer】Ⅱ. 从上到下打印二叉树