6 个有趣的 JavaScript 问题

90 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第10天,点击查看活动详情 Johnny

1. 奇怪的try...catch

执行以下代码会返回什么?2还是3?

(() => {
  try {
    return 2;
  } finally {
    return 3;
  }
})();

答案是3。这是为什么?

这是因为在 try...catch...finally 子句中无论是否抛出异常都会执行。

另外,如果抛出异常,finally即使没有catch处理异常的子句,也会执行子句中的语句。

2. [] 和 null都是objects

接下来的三行代码返回什么?

typeof [];
typeof null;

null instanceof Object;

结果是:

typeof []; // -> 'object'
typeof null; // -> 'object'

null instanceof Object; // false

typeof的返回值如下表所示:

他返回的是字符串'object'。

console.log(typeof 42);
// expected output: "number"

console.log(typeof '@Chris1993');
// expected output: "string"

console.log(typeof true);
// expected output: "boolean"

console.log(typeof undeclaredVariable);
// expected output: "undefined"

但是,可以toString方法检查对象的类型。

Object.prototype.toString.call([]);
// -> '[object Array]'

Object.prototype.toString.call(new Date());
// -> '[object Date]'

Object.prototype.toString.call(null);
// -> '[object Null]'

3. 箭头函数表达式返回未定义

为什么函数f2返回undefined?

let f1 = () => 'javascript';
f1(); // -> 'javascript'

let f2 = () => {};
f2(); // -> undefined

我们以为应该 return {},但是为什么要 return undefined,其实是因为箭头函数返回{}是箭头函数表达式语法的一部分,我们写一个测试用例可以看到:

let f2 = () => {
    return 'javascript'
};
f2(); // -> 'javascript'

也就是说上面例子中的{}语法的一部分,所以f2上面的函数返回undefined。

当然,如果你想返回一个{}对象,你可以把{}它放在括号内:

let f2 = () => ({});
f2(); // -> {}
  1. 函数可以使用反引号执行吗?

除了以下之外,还有其他方法可以调用函数吗?

function f(...args) {
  return args;
}

f(1, 2, 3); // -> [ 1, 2, 3 ]
当然,我们可以使用反引号来调用:
f`Hello string ${'@javascript'}, Hello boolean ${false}, Hello array ${[1, 2, 3]}`;
/*
[
    ["Hello string ",  ", Hello boolean ", ", Hello array ", ""],
    "@Chris1993",
    false,
    [1, 2, 3]
]
*/

这看起来很神奇,但实际上是模板字符串。这是模板字符串的高级形式,带标签的模板字符串。

在上面的示例代码中:f函数是一个模板字面量的标签,该标签可以用来解析模板字符串。

5. JavaScript 中的标签?

以下代码执行输出什么?

foo: {
  console.log("Hello");
  break foo;
  console.log("@javascript");
}

答案是肯定的,它返回字符串Hello。既然foo被识别为一个标签,那么就执行下面的console.log("Hello"),然后执行break foo中断执行。

我们经常使用带标签的语句和break和continue语句来结束或继续循环:

let str = '';

loop1:
for (let i = 0; i < 5; i++) {
  if (i === 1) {
    continue loop1;
  }
  str = str + i;
}

console.log(str);
// expected output: "0234"

developer.mozilla.org/en-US/docs/…

6.{}{}未定义

将它们写入控制台。它们将返回最后一个对象中定义的值。

{}{}; // -> undefined
{}{}{}; // -> undefined
{}{}{}{}; // -> undefined
{foo: 'bar'}{}; // -> 'bar'
{}{foo: 'bar'}; // -> 'bar'
{}{foo: 'bar'}{}; // -> 'bar'
{a: 'b'}{c:' d'}{}; // -> 'd'
{a: 'b', c: 'd'}{}; // > SyntaxError: Unexpected token ':'
({}{}); // > SyntaxError: Unexpected token '{'

检查每个{}时,它们返回未定义。如果你检查{foo: 'bar'}{},你会发现{foo: 'bar'}是'bar'。

{}有两种含义:对象或块。例如,{}in() => {}表示块。所以我们需要使用() => ({})来返回一个对象。

让我们{foo: 'bar'}用作一个块。在控制台中编写此代码段:

if (true) {
  foo: "bar";
} // -> 'bar'

令人惊讶的是,它的行为相同!你可以猜到这里{foo: 'bar'}{}是一个block。👏