返回

JavaScript作用域:理解函数作用域、作用域链和闭包

前端

JavaScript作用域简介

作用域是JavaScript中一个非常重要的概念,它决定了变量和函数在程序中的可见性。JavaScript中只有函数级别的作用域,没有块级作用域。这意味着,只有在进入或者离开函数时,变量和函数的可见性才会发生变化。

函数作用域

函数作用域是指,在函数内部定义的变量和函数只在该函数及其嵌套函数中可见。也就是说,在函数外部无法访问函数内部定义的变量和函数。

function myFunction() {
  var x = 10;

  function innerFunction() {
    console.log(x); // 10
  }

  innerFunction();
}

myFunction();

console.log(x); // ReferenceError: x is not defined

在上面的代码中,变量x在函数myFunction中定义,因此只在myFunction及其嵌套函数innerFunction中可见。在myFunction外部无法访问变量x,因此在最后一行代码中,访问变量x会引发一个ReferenceError

作用域链

作用域链是一个变量或函数在当前作用域中找不到时,会依次向上查找的父作用域链。如果在作用域链中找不到该变量或函数,则会引发一个ReferenceError

function outerFunction() {
  var x = 10;

  function innerFunction() {
    console.log(x); // 10
  }

  innerFunction();
}

outerFunction();

console.log(x); // ReferenceError: x is not defined

在上面的代码中,变量x在函数outerFunction中定义,因此在outerFunction及其嵌套函数innerFunction中可见。在innerFunction中,访问变量x时,会沿着作用域链向上查找,直到找到变量x。因此,在innerFunction中,可以访问变量x。然而,在outerFunction外部无法访问变量x,因此在最后一行代码中,访问变量x会引发一个ReferenceError

闭包

闭包是指,一个函数可以访问其父函数的作用域链中的变量,即使该函数已经离开了其父函数的作用域。

function outerFunction() {
  var x = 10;

  function innerFunction() {
    console.log(x); // 10
  }

  return innerFunction;
}

var inner = outerFunction();

inner(); // 10

在上面的代码中,函数innerFunction是一个闭包,因为它可以访问其父函数outerFunction的作用域链中的变量x,即使innerFunction已经离开了outerFunction的作用域。因此,在innerFunction中,可以访问变量x

闭包在JavaScript中非常有用,它可以用来实现许多高级功能,如:

  • 模块化编程
  • 私有变量
  • 事件处理程序
  • 延迟执行函数