返回

揭秘JavaScript高级知识:作用域、变量提升、自由变量、this、闭包

前端

在JavaScript的领域里,作用域、变量提升、自由变量、this和闭包是绕不开的五个核心概念。理解这些概念,可以让我们在解决复杂问题时得心应手。

作用域

作用域是指变量和函数的可见性范围。在JavaScript中,作用域有两种:全局作用域和局部作用域 。全局作用域是指在整个程序中都可以访问的变量和函数,局部作用域是指只能在函数内部访问的变量和函数。

变量提升

变量提升是指变量在执行代码之前会被提升到作用域的顶部。换句话说,变量在代码中声明的位置并不影响它的实际可用性。例如,下面的代码中,变量a在声明之前就被提升到全局作用域,因此可以在代码的任何位置访问它。

console.log(a); // undefined
var a = 10;

自由变量

自由变量是指在函数内部使用但没有在函数内部声明的变量。自由变量的值在函数内部可以改变,但不能在函数内部重新声明。例如,下面的代码中,变量a在函数内部使用,但没有在函数内部声明。因此,函数内部的a的值可以改变,但不能重新声明。

function foo() {
  console.log(a); // 10
  a = 20;
  //var a = 30; // SyntaxError: Identifier 'a' has already been declared
}

var a = 10;
foo();

this

this指向当前执行代码的对象。this的值在函数内部会发生变化,取决于函数的调用方式。例如,下面的代码中,this的值在函数内部会发生变化,因为函数foo()分别被对象o和全局对象window调用。

var o = {
  name: 'Jack',
  foo: function() {
    console.log(this.name); // Jack
  }
};

o.foo(); // Jack
window.foo(); // undefined

闭包

闭包是指可以访问外部作用域变量的函数。闭包的形成需要满足两个条件:内部函数和自由变量 。内部函数是指在外部函数内部定义的函数,自由变量是指在内部函数内部使用但没有在内部函数内部声明的变量。例如,下面的代码中,函数foo()是一个内部函数,变量a是一个自由变量。因此,函数foo()是一个闭包。

function outer() {
  var a = 10;
  function inner() {
    console.log(a); // 10
  }
  return inner;
}

var foo = outer();
foo();

理解这些概念的必要性

  • 理解作用域可以帮助我们避免变量冲突。
  • 理解变量提升可以帮助我们理解代码的执行顺序。
  • 理解自由变量可以帮助我们理解函数的闭包机制。
  • 理解this可以帮助我们理解对象的方法和属性。
  • 理解闭包可以帮助我们编写出更灵活、更强大的代码。

常见问题及解题思路

  • 以下代码的输出是什么?
function foo() {
  console.log(a); // undefined
  var a = 10;
}

foo();

解题思路:
由于变量提升,a在代码执行之前被提升到全局作用域,因此在函数foo()内部访问a时,它的值为undefined。

  • 以下代码的输出是什么?
function foo() {
  var a = 10;
  function bar() {
    console.log(a); // 10
  }
  return bar;
}

var baz = foo();
baz();

解题思路:
函数foo()返回一个闭包,该闭包可以访问外部作用域变量a。因此,当调用baz()时,a的值为10。

更多资源