这次面试是滴滴业务中台前端方向约我面的一场面试,由于此时正值国庆假期结束,我因为国庆前就拿到了意向,然后假期直接开摆,没啥准备直接上场面试,整体来说本场面试比较看重基础吧
面试题:全局作用域与变量声明
题目: 分析以下 JavaScript 代码的输出。
const a = 1;
console.log(window.a);
答案
在标准的浏览器环境中运行此代码,输出结果是:undefined。
关键知识点解析
这道题主要考察了以下几个核心概念:
-
全局作用域与
window对象:- 在浏览器环境中,顶层作用域(即全局作用域)中声明的变量会作为全局对象的属性。
- 全局对象是
window。因此,直接访问window.a就是在访问全局对象的a属性。
-
变量声明方式的关键区别:
- 使用
var声明的全局变量会自动成为全局对象(window)的属性。var a = 1; console.log(window.a); // 输出:1 - 使用
let和const(ES6 引入)声明的全局变量,虽然也在全局作用域中,但不会被添加到全局对象的属性中。它们存在于一个与全局对象分离的块级作用域中。const a = 1; // 或 let a = 1; console.log(window.a); // 输出:undefined console.log(a); // 输出:1 (变量a本身是存在的,只是不在window上)
- 使用
-
执行环境的影响:
- 浏览器环境:如题所述,输出
undefined。 - Node.js 环境:Node.js 的全局对象是
global,而不是window。因此,直接运行console.log(window.a)会抛出ReferenceError: window is not defined的错误。
- 浏览器环境:如题所述,输出
在 ES6 模块(<script type="module">)中,顶层声明的变量(无论是 var, let 还是 const)都具有模块作用域,而不会成为全局对象的属性,这使得 var 在模块中的行为也发生了变化。
JavaScript 作用域与闭包分析
面试原题
const a = 1
function foo() {
console.log(a)
}
foo()
function bar() {
const a = 2
foo()
}
bar()
运行结果与答案
标准输出结果:
1
1
关键知识点深度解析
这道题的核心是考察 JavaScript 的作用域规则,特别是 词法作用域(Lexical Scope),也称为静态作用域。
-
作用域的基本概念
- 作用域规定了变量和函数的可访问范围。
const、let声明的变量具有块级作用域。
-
词法作用域(核心考点)
- 定义:函数的作用域在函数定义的时候就已经决定了,而不是在函数执行的时候。函数会记住它被创建时所处的词法环境。
- 分析本题:
- 函数
foo是在全局作用域下被定义的。 - 在定义时,它所处的词法环境中,变量
a的值是全局的const a = 1。 - 因此,无论
foo在何处被调用(无论是在全局,还是在bar函数内部),它内部需要访问的变量a,始终指向的是它定义时所在作用域下的那个a,也就是全局的a。
- 函数
-
代码执行步骤分析
第一步:
foo()在全局被调用foo() // 执行 foo 函数,在 foo 函数内部查找 a // -> 查找规则:当前函数作用域没有a -> 向外层(定义时的作用域,即全局)查找 // -> 找到全局的 a = 1 // 输出:1第二步:
bar()被调用,并在其内部调用foo()function bar() { const a = 2 // 这里声明的 a 是 bar 函数的局部变量,与全局的 a 无关 foo() // 关键点:这里只是调用了 foo,但 foo 是在全局定义的! } bar() // 执行过程: // 1. 调用 bar 函数,在 bar 内部创建了局部变量 a = 2。 // 2. 执行 foo()。 // 3. foo 函数开始执行,查找变量 a。 // 4. **foo 函数的作用域链**:foo函数作用域 -> 全局作用域。 // 5. 它并不会去 `bar` 函数的作用域里查找,因为 `bar` 是它的调用者,而不是它的定义者。 // 6. 因此,foo 找到的依然是全局的 a = 1。 // 输出:1
易错点与混淆点
-
误区:认为输出是
1和2。- 产生这种错误的原因是误以为函数的作用域取决于它的调用位置(这被称为“动态作用域”)。
- 但 JavaScript 采用的是词法作用域,只取决于它的定义位置。
-
与
this的规则进行区分:- 函数的
this指向是在调用时才确定的,与调用方式和上下文有关,这一点与变量的作用域查找规则完全不同,切勿混淆。
- 函数的
考察点总结
面试官通过此题希望考察:
- 基础概念:对变量声明(
const)和作用域的理解是否扎实。 - 核心机制:是否深刻理解 JavaScript 的词法作用域机制,这是理解闭包的基础。
- 知识区分:能否清晰区分变量作用域(定义时决定)和
this指向(调用时决定)这两大容易混淆的知识点。
还有一道事件循环题,和两道js手写题,以后发布~