JavaScript 中的五个神秘问题
2023-09-22 11:02:44
JavaScript 中的五个谜题
JavaScript 是当今最流行的编程语言之一,以其动态性和交互性而闻名。然而,这门语言也因其微妙而复杂的特性而臭名昭著。本文将探讨 JavaScript 中的五个谜题,揭示语言中一些经常被误解的概念。
问题 1:浏览器控制台上会打印什么?
var a = 5;
if (true) {
var a = 10;
console.log(a); // 10
}
console.log(a); // 10
这个问题展示了 JavaScript 中变量提升的概念。即使变量在块内重新声明,var 声明也会将变量提升到其所在作用域的顶部。因此,控制台将打印 10 两次。
问题 2:如果我们使用 let 或 const 代替 var,输出是否相同?
let a = 5;
if (true) {
let a = 10;
console.log(a); // 10
}
console.log(a); // 5
const a = 5;
if (true) {
const a = 10; // 报错:TypeError: Assignment to constant variable.
}
console.log(a); // 5
使用 let 或 const 会阻止变量提升,并限制其作用域仅在声明它们的块内。因此,当使用 let 时,控制台将打印 10 和 5,而使用 const 时,则会出现错误。
问题 3:“newArray”中有哪三个值?
const newArray = [1, 2, 3].map((n) => {
return n * 2;
});
console.log(newArray); // [2, 4, 6]
乍一看,newArray 数组似乎包含 [2, 4, 6]。但是,由于箭头函数中的隐式返回,该数组实际上包含三个 undefined 值。这是因为箭头函数中没有大括号,这意味着自动插入一个返回语句。
问题 4:为什么箭头函数中的 this 指向 Window 对象?
const obj = {
name: "JavaScript",
printName: () => {
console.log(this.name); // undefined
},
};
obj.printName();
箭头函数中的 this 关键字与它们所在的词法作用域有关,而不是其调用者的作用域。因此,obj.printName() 将输出 undefined,而不是预期的 “JavaScript”。
问题 5:这个闭包会做什么?
function createCounter() {
let count = 0;
return function() {
return count++;
};
}
const counter1 = createCounter();
const counter2 = createCounter();
console.log(counter1()); // 0
console.log(counter1()); // 1
console.log(counter2()); // 0
console.log(counter2()); // 1
这个函数返回一个闭包,该闭包可以访问其创建时的外部变量(count)。因此,counter1 和 counter2 拥有各自的私有计数器变量,并且不会相互影响。
理解这些谜题对于写出可靠且高效的 JavaScript 代码至关重要。通过掌握这些概念,你可以提高你的编程技能,并创建更有弹性、更易于维护的应用程序。