返回

,#keyword,#description { display:none; } </style> 搞懂这道 JS 面试题,还有助于理解闭包等高级概念

前端

题干

(function() {
  var foo = 100;
  foo = 1;
  console.log(foo); // 100
})();
console.log(foo); // 1

解析

这道题考察了 JavaScript 的作用域和变量提升机制。

首先,JavaScript 的作用域分为全局作用域和局部作用域。全局作用域是整个程序都可以访问的作用域,局部作用域是函数内部的作用域,只在函数内部有效。

其次,JavaScript 中的变量提升是指在代码执行之前,所有的变量声明都会被提升到函数或者全局作用域的顶部。

基于以上两点,我们可以理解这道题的运行过程如下:

  1. 首先,由于变量提升,变量 foo 被提升到函数的顶部。此时,foo 的值为 undefined
  2. 然后,函数执行,局部变量 foo 被重新赋值为 100
  3. 接着,函数中的 console.log(foo) 语句执行,输出 100
  4. 最后,函数执行完毕,局部变量 foo 被销毁。
  5. 然后,全局作用域中的 console.log(foo) 语句执行,输出 1

总结

通过这道题,我们可以了解到 JavaScript 的作用域和变量提升机制,以及它们是如何影响代码的执行结果的。同时,我们还可以了解到,即使是一道看似简单的面试题,也可能暗藏玄机,需要我们深入理解 JavaScript 的运行机制才能回答正确。

附录

闭包

闭包是指在函数内部定义的函数,可以访问函数内部的变量,即使函数已经执行完毕。闭包在 JavaScript 中有很多应用,比如实现私有变量、事件处理、定时器等。

实例

下面是一个使用闭包实现私有变量的实例:

function Person(name) {
  var age = 20; // 私有变量

  function getAge() {
    return age;
  }

  this.getName = function() {
    return name;
  };

  this.setAge = function(newAge) {
    age = newAge;
  };

  this.getInfo = function() {
    return `${this.getName()} is ${this.getAge()} years old.`;
  };
}

var person = new Person('John');
console.log(person.getInfo()); // John is 20 years old.

person.setAge(30);
console.log(person.getInfo()); // John is 30 years old.

在这个实例中,函数 getAge 是一个闭包,它可以访问函数 Person 内部私有变量 age。通过函数 getNamesetAgegetInfo,我们可以对私有变量 age 进行操作。

小结

闭包是 JavaScript 中一个非常重要的概念,它可以帮助我们实现私有变量、事件处理、定时器等功能。理解闭包的原理,可以帮助我们更深入地理解 JavaScript 的运行机制。