重温JavaScript(lesson3):作用域和闭包

Posted 重温新知

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了重温JavaScript(lesson3):作用域和闭包相关的知识,希望对你有一定的参考价值。

在lesson1关于let的回顾中我们涉及到了块级作用域的概念,我们了解到JS中包括全局作用域、函数作用域还有块级作用域。这次,我们详细地学习一下有关作用域的相关知识。安利一本不错的书《你不知道的javascript(上卷)》,这本书的整个第一部分都在讲作用域和闭包的内容。那我们就进入到作用域有关知识的学习:

1.作用域的概念

关于作用域的概念,New_Name看到w3school 是这样说的:<font color=red>作用域指的是您有权访问的变量集合。</font>《你不知道的JavaScript(上卷)》对作用域的角色定义为:<font color=red>作用域是负责收集并维护由所有声明的变量组成的一系列查询,并且实施一套严格的规则,确定当前执行的代码对这些变量的访问权限</font>。《JavaScript编程精粹》一书对作用域下的定义是:<font color=red>一个变量的作用域就是该变量所在的上下文。作用域指明了可以从哪里访问到某个变量,以及在该上下文中是否可以访问这个变量。</font>

总而言之,作用域的作用就是控制程序对变量的访问。

2.作用域的分类

作用域可以分为全局作用域和局部作用域。局部作用域又可以分为函数作用域和块级作用域。

<font color=red>在JS中,每个函数创建一个新的作用域,我们称之为函数作用域</font>。从函数外部无法访问函数内部定义的变量。

function testFun() {
    var test = 10;
    console.log(test);
}
function testFun2() {
    var test = 11;
    console.log(test);
}
testFun();//10
testFun2();//11
console.log(test);// test is not defined

从以上代码中我们看到:(1)可以在不同函数中使用同名变量,彼此不会相互影响。(2)从函数外部无法访问函数内部定义的变量。再看另外一段代码:

var test = 9;
function testFun() {
    console.log(test);//undefined
    var test = 10;
    console.log(test);//10
}
testFun();
console.log(test);//9

这段代码中,testFun内部声明的test处于函数作用中,而在函数外部声明的test处于全局作用域中。在函数作用域内,访问和全局作用域同名的test时,访问的是函数作用域的变量。我们再来看一段代码:

var test = 9;
function testFun() {
    console.log(test);//9
      test = 10;
    console.log(test);//10
}
testFun();
console.log(test);//10

这段代码,在全局作用域内声明了test并赋初值9,然后我们看到在函数作用内可以访问全局作用内的值,并且可以对其修改。

之前说过,以前JS是没有块作用域的概念,ES6引进了let关键字,可以用于生成块级作用域。

var foo = true;
if (foo) {
    let bar = \'New_Name\';
    console.log(bar);//New_Name
}
console.log(bar);//bar is not defined

在如上代码中,变量bar是声明在了块作用域内的,块外部无法访问到bar的值。下面来看看作用域链是神马~

3.作用域链的概念

通常,变量的取值都是到创建此变量的作用域中取值。但是<font color=red>如果在当前作用域中没有查到值,就会向上级作用域去查,直到查到全局作用域,此查找过程形成的链条就叫做作用域链</font>。看一下代码:

var globalTest = 10
function funcDomin(flag) {
    var funcTset = 9;
    if (flag === true) {
        let blockTest = 8;
        console.log(blockTest);//8
        console.log(funcTset);//9
        console.log(globalTest);//10
    }
}
funcDomin(true);

在块级作用域中访问blockTest,由于blockTest存在域当前作用域内,就不向上查找了。接着访问funcTest,由于funcTest不在当前的块级作用域内,就向上级作用域也就是funcTest所在的函数作用域中去查找,找到了就不再向上查找。而globalTest的情况也类似,只不过还要向上一级查找,直到全局作用域。

好了,这就是本次学习的全部内容了,下一次我们将一起探索有关闭包的内容。

如有错误,请不吝指正。温故而知新,欢迎和我一起重温旧知识,攀登新台阶~

以上是关于重温JavaScript(lesson3):作用域和闭包的主要内容,如果未能解决你的问题,请参考以下文章

重温JavaScript(lesson2):关于ES6中的const

JavaScript 开发进阶:理解 JavaScript 作用域和作用域链

JavaScript 开发进阶:理解 JavaScript 作用域和作用域链

(转)JavaScript 开发进阶:理解 JavaScript 作用域和作用域链

python作用域和JavaScript作用域

JavaScript 作用域