JS作用域链

函数作用域

  1. 定义:
    作用域(scope)指的是变量存在的范围。在 ES5 的规范中,JavaScript 只有两种作用域:
    全局作用域:变量在整个程序中一直存在,所有地方都可以读取。
    函数作用域:变量只在函数内部存在。
    ES6 又新增了块级作用域。

  • 对于顶层函数来说,函数外部声明的变量就是全局变量(global variable),它可以在函数内部读取。
var a=1;
function fn(){
  console.log(a); // 1
}
fn(); // 1

上面的代码中,变量a在函数fn外部定义(即是全局变量a),函数fn内部的console.log(a)可以读取全局变量a


  • 在函数内部定义的变量,外部无法读取,称为“局部变量”(local variable)。
function fn(){
  var a=1;
}
console.log(a); // ReferenceError: a is not defined
fn();

上面代码中,变量a在函数fn内部定义,所以是一个局部变量,函数fn之外的console.log(a)就无法读取变量a


  • 函数内部定义的变量,会在该作用域内覆盖同名全局变量。
var a = 1;
function fn(){
  var a = 2;
  console.log(a); // 2
}
fn(); // 2
console.log(a); // 1

上面代码中,变量a同时在函数的外部和内部都有定义。结果,在函数内部定义,局部变量a覆盖了全局变量a,(即函数fn内部的console.log(a)只读取var a=2所以fn()输出2)。


  • 对于var命令来说,局部变量只能在函数内部声明,在其他区块中声明,一律都是全局变量。
if (true) {
  var x = 5;
}
console.log(x);  // 5

上面代码中,变量x在条件判断区块之中声明,结果就是一个全局变量,可以在区块之外读取。


那么什么是作用域链呢?

var a=1;
function fn(){
  console.log(a); // 1
}
fn(); // 1
var a = 1;
function fn(){
  var a = 2;
  console.log(a); // 2
}
fn(); // 2

从上面两段代码中,我们可以得知我们在查找变量a时,先在函数作用域中(即函数fn内部)查找并读取变量a,如果没有找到,再去全局作用域中查找并读取。你会注意到,这是一个从内往外层查找(从下往上查找)的过程。我们把这个整个查找的过程称之为作用域链

原理

  1. 函数在执行的过程中,先从自己内部找变量并读取。
  2. 如果找不到,再从创建当前函数所在的作用域去找, 以此往上。
  3. 注意找的是变量的当前的状态。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 一、作用域 一个变量的作用域(scope)是程序源代码中定义的这个变量的区域。 在JS中使用的是词法作用域(lex...
    博闻强记富内斯阅读 873评论 0 5
  • 一、闭包: 概念:闭包实际上就是一个函数,与一般函数不同的是它能访问其他函数里的变量。(另一个特点就是被内部函数访...
    啊哈_57ea阅读 207评论 0 0
  • 之前写过一篇JavaScript 闭包究竟是什么的文章理解闭包,觉得写得很清晰,可以简单理解闭包产生原因,但看评论...
    宁骥阅读 348评论 0 1
  • 纯干货,没有废话 先看题目,诸位自测 题目1 题目2 题目3 结果 解密 1、函数在执行时先从自己内部的局部作用域...
    allen_tian阅读 240评论 0 0
  • 函数声明和函数表达式有什么区别? 1.声明的函数foo将会在执行前提升,因此foo在函数上下文都是可以被调用的,即...
    小囧兔阅读 308评论 0 1