关于前端:6-个意想不到的-JavaScript-问题

26次阅读

共计 2614 个字符,预计需要花费 7 分钟才能阅读完成。

作为前端开发工程师,JavaScript 是咱们的次要开发语言,它自身语法比较简单,并且生态系统也十分欠缺,在社区的影响力越来越大。

在咱们应用过程中,常常会遇到各种奇怪的问题,让咱们常常摸不着头脑。

本文灵感来自 wtfjs,整顿了 6 个比拟常见并且很有意思的问题。

1. 奇怪的 try..catch

❓问题

上面代码执行后将返回什么?2 还是 3

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

💡解答

答案是 3,这是为什么呢?这是因为在 try...catch...finally 语句中,无论是否抛出异样 finally 子句都会执行。此外,如果抛出异样,即便没有 catch 子句解决异样,finally 子句中的语句也会执行。

📚参考

  • MDN try…catch

2. []null 都是对象

❓问题

上面 3 行代码返回后果是什么?

typeof [];
typeof null;

null instanceof Object;

💡解答

返回后果是这样的:

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

null instanceof Object; // false

typeof 操作符返回一个字符串,且必须合乎 Table 37: typeof 操作符 返回值。对于没有实现 [[Call]]null、一般对象、规范特异对象和非标准特异对象,它返回字符串 'object'

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

console.log(typeof '前端自习课');
// 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]'

📚参考

  • MDN typeof

3. 箭头函数返回 undefined

❓问题

函数 f2 执行后为什么返回了 undefined

let f1 = () => '前端自习课';
f1(); // -> '前端自习课'

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

💡解答

咱们第一眼感觉应该是返回 {},可是却返回了 undefined,这实质起因是因为箭头函数返回的 {} 是箭头函数语法的一部分,咱们写一个测试用例就能看进去:

let f2 = () => {return '前端自习课'};
f2(); // -> '前端自习课'

因而下面 f2 函数返回的是 undefined,当然,如果须要返回一个 {} 对象也是能够的,只须要应用括号将返回值包裹起来:

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

4. 还能应用反引号执行函数?

❓问题

调用函数除了上面的形式,还有其余形式吗?

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

f(1, 2, 3); // -> [1, 2, 3]

当然还有啦,咱们能够应用 反引号 调用:

f`Hello string ${'前端自习课'}, Hello boolean ${false}, Hello array ${[1, 2, 3]}`;
/*
[["Hello string",  ", Hello boolean", ", Hello array", ""]," 前端自习课 ",
    false,
    [1, 2, 3]
]
*/

💡解答

这个看着很神奇的样子,然而实际上用的是模版字符串。这是一种高级模式的模版字符串,是带标签的模版字符串。

下面示例代码中:f 函数是模版字面量的标签,标签能够用函数解析模板字符串。标签函数的第一个参数蕴含一个字符串值的数组。其余的参数与表达式相干。

📚参考

  • MDN 模版字符串。

5. JavaScript 中也有标签?

❓问题

上面这种写法会有问题吗?

foo: {console.log("Hello");
  break foo;
  console.log("前端自习课");
}

💡解答

答案是没问题,会返回 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"

📚参考

  • MDN label

6. {}{}undefined

❓问题

咱们能够在控制台测试上面代码。相似这样的构造会返回最初定义的对象中的值。

{}{}; // -> 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 '{'

💡解答

当解析到 {} 会返回 undefined,而解析 {foo: 'bar'}{} 时,表达式 {foo: 'bar'} 返回 'bar'

这里的 {} 有两重含意:示意 对象 ,或示意 代码块

例如,在 () => {} 中的 {} 示意 代码块。所以咱们必须加上括号:() => ({}) 能力让它正确地返回一个对象。

因而,咱们当初将 {foo: 'bar'} 当作 代码块 应用,则能够在终端中这样写:

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

啊哈,一样的后果!所以 {foo: 'bar'}{} 中的花括号就是示意 代码块

欢送关注我,我将分享更多有用的内容~

正文完
 0