JavaScript面试问题:常见问题

来自菜鸟教程
跳转至:导航、​搜索

在 JavaScript 中,在您发现它们之前,有些技术性的东西一开始并不十分有意义。 现在,每个人都有自己的 JavaScript 陷阱列表,但诸如“JavaScript 区分大小写”之类的东西并不是真正的陷阱。 对我来说,应该是这样。 这不是一个令人困惑的技巧。 这种方式只是技术性的。

对我来说,真正的“陷阱”是 1 == 11 == '1' 为真,但 [] == [] 不为真。 尽管这是更简单的“陷阱”之一,但在您深入研究“为什么”之前,它仍然不会立即显得直观。

在本指南中,我们将介绍您在 JavaScript 面试中可能会发现的一些常见问题。 面试官可能不会直接问这些问题,但他们可能会问你一些与他们相关的事情,或者做一个涉及他们的问题。

var 对比 让

这是最基本的问题之一 - 起初 var 和 let 关键字似乎与我非常相似,我看不出有什么区别。 但是,这是显示差异的常用方法:

// let
for(let i=0; i<10; i++) {
  //...
}
console.log(i) // Reference Error: i is not defined

// var
for(var j=0; j<10; j++) {
  //...
}
console.log(j) // 10

一个很大的区别是 let 是块范围的 - 这意味着它仅限于定义它的任何块。 为了让 console.log 知道 i 是什么,您必须从 for 循环中 提升 i。 这正是 var 在幕后所做的。 var 关键字是函数范围的,如中所示,仅受父函数限制。 并自动提升到声明它的块之外。

加法与串联

1 + 1; // 2, obviously
1 + "1"; // "11"

如您所见,JavaScript 将数字转换为字符串。 或者是吗?

1 - "1"; // 0 (number)
1 * "1"; // 1 (number)
1 / "1"; // 1 (number)
"1" * "1"; // 1 (yep, still a number)

不,实际上 JavaScript 在大多数情况下会将字符串转换为数字。 对于 + 运算符,它是连接而不是相加的。 串联,如字符串:"your" + "name" // "your name"

南陷阱

NaN 代表“不是数字”。 这是在 JavaScript 中处理的更令人困惑的(“数字”?)之一。 例如:

NaN === NaN; // false
NaN == NaN; // false as well
typeof NaN; // number
"" == NaN; // false

事实上,任何等于“NaN”的东西都是错误的,尽管有很多“不是数字”的东西。 这就是为什么您必须使用 isNaN()。 但即使这样也可能令人困惑:

isNaN("string"); // true - what we would expect, as a string is not a number
isNaN(123); // false - also expected
// false means it's a number, right?

isNaN(""); // false - hmm...
isNaN("45"); // false - this is a string, I thought
isNaN([]); // false - wait so an empty array is a number?

isNaN([1, 2]); // true
isNaN({}); // true
isNaN(() => {}); // true

平等/真实与虚假

您可能已经熟悉 ===== 之间的区别。 == 只检查值,而 === 包括类型检查。 这就是为什么 1 === "1" 为假,而 1 == "1" 为真的原因。 但是,您知道这是真的吗:null == undefined。 但当然,这是对 == 的松散检查。

还有 != 表示“不相等”。 这是真的:null !== undefined,但这是假的 null != undefined。 下列的? 基本上,第一个是说,“null 不完全等于 undefined”,而第二个说,“null is not not not not notally equal to undefined”(双重否定,意味着它们是松散相等的)。

但是,让我们看看更多比较复杂的比较。 这些都是真实的:

false == '0' // true
0 == false   // true
'' == 0      // true
false == ''  // true
[] == ''     // true, but we'll get to this

'1' == true  // true
1 == true    // true
'false' == true // true

这些是令人困惑的比较检查,但它们在技术上并不真实。 假的。 它们只是值检查,因为记住 []==[] 结果是假的,然而,“[]”是一个真值。 检查真假的方法是将事物放入 if 块中。 例如:

if ("") {
  console.log(true);
} else {
  console.log(false);
}
// logs false

//But look at this
if ([]) {
  console.log(true);
}
// logs true - an empty array is still truthy

if ([] == "") {
  console.log(true);
}
// logs true - but look at the first one - it logged false

空对象 {} 也记录为真。 JavaScript 在平等和类型方面非常有趣,但我建议使用三等号 ===!== 进行比较。

现在,最后一个例子很好地说明了关键区别。 松散的平等检查,检查价值,不一定是假的/真实的。 if 块检查虚假/真实。 看,在 JavaScript 中这是真的:[] == false。 但正如我们在上面看到的,一个 if 块检查一个空数组是否为真。 显然,if(false) 不会去任何地方。

自动分号插入

我注意到,如果我忘记添加分号来结束一行代码,它不会给我一个错误。 在幕后 自动分号插入 插入缺少的分号,这没关系,但可能会养成一个坏习惯。 有些语句需要分号,否则 JavaScript 可能不知道它们已经结束,而其他的,正如我们将看到的,根本没有结束,但 JavaScript 认为它已经结束。

function increment(num) {
  return
  ++num
}
console.log(increment(3))

现在这不是世界上最好的例子,但它返回 undefined 可能会让您感到惊讶。 那是因为在“return”的末尾偷偷地插入了一个分号,并且永远不会到达下一行代码。 有点像这样:

function increment(num) {
  return;
  ++num;
}
console.log(increment(3));

全局变量

最后,JavaScript 有这种凭空创建全局变量的奇怪行为。 这又回到了我们处理 letvar 关键字的第一个问题。

还记得我们说过 let 是块作用域,而 var 是函数作用域吗? 那这是什么?

for(i = 0; i < 10; i++) {
  // ...
}
console.log(i); // 10

注意我们做了什么? “i”变量没有定义:i=0。 结果是什么? 创建了一个全局变量。 这是一件危险的事情,因为现在我们的 i 变量是全局变量。

在任何函数中也是如此:function someFn() { someVar = 0; }。 这里的 someVar 变成了一个全局变量,类似于说 window.var = 0

结论

JavaScript 有一些难以驾驭的东西,事实上面试官会问你这些问题,即使你在现实生活中几乎看不到它们。 但是,你要做什么?

好消息是,有大量的文档和视频教学可以向您展示这些内容。 我建议您搜索“JavaScript 棘手的面试问题”或“JavaScript 棘手的问题”之类的内容。 即使你没有在面试中得到他们,至少你知道他们将来是否会出现问题。 另外,你也可以用他们来欺骗你的朋友!

祝你好运,当有疑问时,请记住这些是所有开发人员都面临的事情 - 你并不孤单!