返回

JS作用域与作用域链

前端

JavaScript 中的作用域

作用域(Scope)是 JavaScript 中一个非常重要的概念,它决定了变量和函数的生存范围。在 JavaScript 中,作用域分为全局作用域和局部作用域,局部作用域又分为函数作用域和块级作用域。

全局作用域

全局作用域是整个 JavaScript 程序的生存范围,在这个作用域中声明的变量和函数可以在程序的任何地方访问。

var globalVariable = 1;

function globalFunction() {
  console.log(globalVariable);
}

globalFunction(); // 1

局部作用域

局部作用域是函数体内的生存范围,在这个作用域中声明的变量和函数只能在函数体内访问。

function localFunction() {
  var localVariable = 2;

  function innerFunction() {
    console.log(localVariable);
  }

  innerFunction(); // 2
}

localFunction(); // ReferenceError: localVariable is not defined

块级作用域

块级作用域是 ES6 中引入的新概念,它允许在代码块中声明变量和函数,这些变量和函数只能在代码块内部访问。

{
  let blockVariable = 3;

  function blockFunction() {
    console.log(blockVariable);
  }

  blockFunction(); // 3
}

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

作用域链

作用域链(Scope Chain)是 JavaScript 中一个重要的概念,它决定了变量和函数的查找机制。当 JavaScript 引擎执行代码时,它会创建一个作用域链,作用域链是从内到外依次查找变量和函数,直到找到为止。

function outerFunction() {
  var outerVariable = 1;

  function innerFunction() {
    var innerVariable = 2;

    console.log(outerVariable); // 1
    console.log(innerVariable); // 2
  }

  innerFunction();
}

outerFunction();

在这个例子中,作用域链如下:

  • 内层作用域:innerFunction 函数的作用域
  • 外层作用域:outerFunction 函数的作用域
  • 全局作用域:整个 JavaScript 程序的作用域

当 JavaScript 引擎执行 console.log(outerVariable); 时,它会在 innerFunction 函数的作用域中查找 outerVariable 变量,没有找到,于是它会继续在 outerFunction 函数的作用域中查找,找到了 outerVariable 变量,于是输出 1

当 JavaScript 引擎执行 console.log(innerVariable); 时,它会在 innerFunction 函数的作用域中查找 innerVariable 变量,找到了 innerVariable 变量,于是输出 2

JavaScript 中的作用域提升

作用域提升(Hoisting)是 JavaScript 中一个非常重要的概念,它会导致变量和函数在代码执行之前就已经被提升到了作用域的顶部。

变量提升

变量提升是指变量在代码执行之前就已经被提升到了作用域的顶部,并且被赋予了 undefined 值。

console.log(a); // undefined

var a = 1;

在这个例子中,变量 a 在代码执行之前就被提升到了全局作用域的顶部,并且被赋予了 undefined 值。当 console.log(a); 语句执行时,它会输出 undefined

函数提升

函数提升是指函数在代码执行之前就已经被提升到了作用域的顶部。

console.log(f); // function f() { ... }

function f() {
  console.log('Hello world!');
}

f(); // Hello world!

在这个例子中,函数 f 在代码执行之前就被提升到了全局作用域的顶部。当 console.log(f); 语句执行时,它会输出 function f() { ... }。当 f(); 语句执行时,它会调用函数 f,输出 Hello world!

JavaScript 中的作用域闭包

作用域闭包(Closure)是 JavaScript 中一个非常重要的概念,它允许函数访问其定义时的作用域,即使该函数已经被返回或者执行完毕。

function outerFunction() {
  var outerVariable = 1;

  return function() {
    console.log(outerVariable); // 1
  };
}

var innerFunction = outerFunction();

innerFunction(); // 1

在这个例子中,outerFunction 函数返回了一个匿名函数,这个匿名函数被称为闭包。闭包可以访问 outerFunction 函数的作用域,即使 outerFunction 函数已经被返回或者执行完毕。当 innerFunction 函数执行时,它会输出 1

总结

作用域是 JavaScript 中一个非常重要的概念,它决定了变量和函数的生存范围。作用域链是 JavaScript 中另一个重要的概念,它决定了变量和函数的查找机制。作用域提升是 JavaScript 中一个非常重要的概念,它会导致变量和函数在代码执行之前就已经被提升到了作用域的顶部。作用域闭包是 JavaScript 中一个非常重要的概念,它允许函数访问其定义时的作用域,即使该函数已经被返回或者执行完毕。