作用域

2019-07-28  本文已影响0人  你喜欢吃青椒吗_c744

什么是作用域

作用域就是一套规则,用于确定在何处以及如何查找变量(标识符)的规则。
通俗的讲,作用域就是查找变量的地方。

查找变量

function foo() {
    var a = 'iceman';
    console.log(a); // 输出"iceman"
}
foo();

在foo函数执行的时候,输出一个a变量,那么这个a变量是哪里来的嘞,有看到函数第一行有定义a变量的代码var a = 'iceman'


再看一段同样简单的代码

var b = 'programmer';
function foo() {
    console.log(b); // 输出"programmer"
}
foo();

同样的道理,在输出b的时候,自己函数内部没有找到变量b,那么就在外层的全局中查找,找到了就停止查找并输出了。



通俗的讲,作用域就是查找变量的地方。在某函数中找到该变量,就可以说在该函数作用域中找到了该变量;在全局中找到该变量,就可以说在全局作用域中找到了该变量!

作用域链

我们在查找b变量的时候,先在函数作用域中查找,没有找到,再去全局作用域中查找,有一个往外层查找的过程。我们好像是顺着一条链条从下往上查找变量,这条链条,我们就称之为作用域链。

作用域嵌套

在还没有接触到ES6的let、const之前,只有函数作用域和全局作用域,函数作用域肯定是在全局作用域里面的,而函数作用域中又可以继续嵌套函数作用域,如图:


image.png

用代码显示:


image.png

查找变量是顺着红色的箭头走的,从里到外,这从里到外的各层作用域就组成了作用域链。

作用域中变量(标识符)的查找规则

首先声明一点,JavaScript是有编译过程的,不要惊讶,真的有!也就是说var name = 'iceman'这段代码,其实这是有两个动作的:

其实编译器是这样工作的,在代码执行之前从上到下的进行编译,当遇到某个用var声明的变量的时候,先检查在当前作用域下是否存在了该变量。如果存在,则忽略这个声明;如果不存在,则在当前作用域中声明该变量。

词法作用域

所谓的词法作用域就是在你写代码时将变量和块作用域写在哪里来决定,也就是词法作用域是静态的作用域,在你书写代码时就确定了。

function fn1(x) {
    var y = x + 4;
    function fn2(z) {
        console.log(x, y, z);
    }
    fn2(y * 5);
}
fn1(6); // 6 10 50

这个例子中有个三个嵌套的作用域,如图:


image.png

在此强调,词法作用域就是作用域是由书写代码时函数声明的位置来决定的。编译阶段就能够知道全部标识符在哪里以及是如何声明的,所以词法作用域是静态的作用域,也就是词法作用域能够预测在执行代码的过程中如何查找标识符。

转载于

深入理解闭包之前置知识→作用域与词法作用域

上一篇下一篇

猜你喜欢

热点阅读