博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
大话javascript 1期:作用域和作用域链
阅读量:5922 次
发布时间:2019-06-19

本文共 3286 字,大约阅读时间需要 10 分钟。

一、什么是作用域?

作用域是你的代码在运行时,各个变量、函数和对象的可访问性。(可产生作用的区域)

二、JavaScript中的作用域

在 JavaScript 中有两种作用域

  • 全局作用域
  • 局部作用域

当变量定义在一个函数中时,变量就在局部作用域中,而定义在函数之外的变量则从属于全局作用域。每个函数在调用的时候会创建一个新的作用域。

1.全局作用域

当你在文档中(document)编写 JavaScript 时,你就已经在全局作用域中了。JavaScript
文档中(document)只有一个全局作用域。
定义在函数之外的变量会被保存在全局作用域中
// 作用域默认为全局作用域var name = 'andy';

全局作用域里的变量能够在其他作用域中被访问和修改

var name = 'andy';console.log(name); // 输出 'andy'function logName() {    console.log(name); // 'name' 变量可以在这里和其他地方访问}logName(); // 输出 'andy'

2.局部作用域

定义在函数中的变量就在局部作用域中。并且函数在每次调用时都有一个不同的作用域。这意味着同名变量可以用在不同的函数中。因为这些变量绑定在不同的函数中,拥有不同作用域,彼此之间不能访问。
// 全局作用域function someFunction() {    // 局部作用域 ##1    function someOtherFunction() {        // 局部作用域 ##2    }} // 全局作用域function anotherFunction() {    //局部作用域 ##3}

3.块语句(JS没有块级作用域)

块级声明包括if和switch,以及for和while循环,和函数不同,它们不会创建新的作用域。在块级声明中定义的变量从属于该块所在的作用域。也就是说在for、if、while等语句内部的声明的变量与在外部声明是一样的,在这些语句外部也可以访问和修改这些变量的值。
if (true) {    //这里的if条件不会创建一个新的作用域    var name = 'Hammad'; // name 这个变量仍在全局作用域}console.log(name); // logs 'Hammad'

ECMAScript 6 引入了let和const关键字。这些关键字可以代替var

var name = 'Hammad';let likes = 'Coding';const skills = 'Javascript and PHP';

和var关键字不同,let和const关键字支持在块级声明中创建使用局部作用域(块级作用域)

if (true)     // 这个 'if' 块语句没有创建一个块级作用域    // name 变量处于全局作用域,因为由var关键字声明    var name = 'Hammad';    // likes 变量处于块级作用域因为由let关键字声明    let likes = 'Coding';    // skills 变量处于块级作用域因为由const关键字声明    const skills = 'JavaScript and PHP';}console.log(name); // 输出 'Hammad'console.log(likes); // Uncaught ReferenceError: likes is not definedconsole.log(skills); // Uncaught ReferenceError: skills is not defined

一个应用中全局作用域的生存周期与该应用相同。局部作用域只在该函数调用执行期间存在

4.词法作用域

所谓的 词法( 代码 )作用域, 就是代码在编写过程中体现出来的作用范围. 代码一旦写好, 不用执行, 作用范围就已经确定好了.
这个就是所谓词法作用域.这意味着
函数运行在定义它的作用域中,而不是在调用它的作用域中

在 js 中词法作用域规则:

  • 函数允许访问函数外的数据.
  • 整个代码结构中只有函数可以限定作用域.
  • 作用规则首先使用提升规则分析
  • 如果当前作用规则中有名字了, 就不考虑外面的名字

词法作用域

var用来将变量定义在词法作用域中(也就是function中)

function someFunc(){    var a;}

a就被函数someFunc框在了词法作用域中

块级作用域

letconst用来将变量定义在块级作用域中(也就是花括号中)

if(true){    let b;}

b就被if的花括号框在了块级作用域中

5.作用域链

可以发现只有函数可以制造作用域结构. 那么只要是代码, 至少有一个作用域, 即全局作用域. 凡是代码中有函数,那么这个函数就构成另一个作用域. 如果函数中还有函数, 那么再这个作用域中就 又可以诞生一个作用域. 那么将这样的所有的作用域列出来,可以有一个结构:
函数内指向函数外的链式结构.

作用域嵌套

作用域是可以嵌套的,任务一中提到的词法作用域和块级作用域都可以嵌套其他作用域

(块级作用域仅对ES6而言)

function someFunc(){    function inner(){    }}

inner就是嵌套在someFunc(词法作用域)中的词法作用域

if(true){    while(false){    }}

while就是嵌套在if(块级作用域)中的块级作用域

function someFunc(){    if(true){    }}

if就是嵌套在someFunc(词法作用域)中的块级作用域

作用域中的变量访问

所有的嵌套作用域都遵循以下规则:

内部作用域有权访问外部作用域,反之不成立。

栗子:

function someFunc(){

var outerVar = 1;function inner(){    var innerVar = 2;}

}

inner有权访问innerVarouterVar,但是someFunc只能访问到outerVar

多重嵌套作用域

作用域是可以任意嵌套的,但是都要遵循上面的规则。

再附加一个规则:
兄弟作用域不可相互访问

栗子:

function someFunc(){    function inner(){    }    function inner2(){    }}

innerinner2都是someFunc中的作用域,正如someFunc不能访问inner们的作用域一样,inner们之间也不能相互访问。

作用域树

从上向下看这个嵌套作用域,就是棵树!

看代码:

function someFunc() {  function inner() {  }  function inner2() {    function foo() {    }  }}

看树:

someFunc()       |      / \     /   \    /     \   ↓       ↓inner()  inner2()           |           ↓         foo()

要记住的是:inner作用域可以访问外部作用域,但是反之不成立; foo()可以访问inner2()中的变量,inner2()可以访问someFunc()中的变量,这棵树倒过来似乎更有意义,就成了链!!

作用域链

从最里面看到最外面就构成了作用域链

someFunc()       ↑        \         \          \         inner2()           ↑           |         foo()

转载地址:http://twsvx.baihongyu.com/

你可能感兴趣的文章
Linq之Linq to Objects
查看>>
python全栈开发笔记---------数据类型---字典方法
查看>>
ios项目中引用其他开源项目
查看>>
分治优化决策单调性
查看>>
Nginx与Apache简单对比
查看>>
常见的HTTP返回状态值
查看>>
Centos防火墙添加IP白名单
查看>>
OpenCV学习笔记——疑问
查看>>
Mac使用brew安装nginx,并解决端口访问权限问题
查看>>
【云图】如何建立北京三甲医院云图,不用数据库持有自己数据!
查看>>
分布拟合——正态/拉普拉斯/对数高斯/瑞利 分布
查看>>
Codeforces Round #331 (Div. 2)
查看>>
构造 hihocoder 1257 Snake Carpet (15北京I)
查看>>
Queue学习
查看>>
构造水题 Codeforces Round #206 (Div. 2) A. Vasya and Digital Root
查看>>
nRF5 SDK for Mesh(一) 介绍和下载源码
查看>>
SPRING 集成 KAFKA 发送消息
查看>>
spark-reduceByKey算子
查看>>
Visual C#网络编程技术与实践(配光盘)(网络编程系列丛书)
查看>>
C语言队列的实现
查看>>