每日面试题

每日面试题

输出以下代码运行结果,为什么?如果希望每隔 1s 输出一个结果,应该如何改造?注意不可改动 square 方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const list = [1, 2, 3]
const square = num => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(num * num)
}, 1000)
})
}

function test() {
list.forEach(async x => {
const res = await square(x)
console.log(res)
})
}
test()
  • forEach是不能阻塞的,默认是请求并行发起,所以是同时输出1、4、9
  • 解决方案
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    async function test() {
    for (let i = 0; i < list.length; i++) {
    let x = list[i]
    const res = await square(x)
    console.log(res)
    }
    }
    async function test() {
    for (let x of list) {
    const res = await square(x)
    console.log(res)
    }
    }
    ## axios 源码里所用到的,利用 promise 本身的链式调用来实现串行
    let promise = Promise.resolve()
    function test(i = 0) {
    if (i === list.length) return
    promise = promise.then(() => square(list[i])).then((res) => {
    console.log(res);
    })
    test(i + 1)
    }
    ## 利用promise的链式调用
    function test() {
    let promise = Promise.resolve()

    list.forEach(x => {
    promise = promise.then(() => square(x)).then((res) => {
    console.log(res)
    })
    })
    }
标记的模板字符串
  • 第一个参数包含所有的静态字符串,以表达式变量进行分割成数组(类似split(‘$’)的效果);然后逐一解析变量表达式,传到对应的参数第二个参数、第三个参数
  • 拓展:参数传递的对象和我们用于检查相等性的对象在内存中位于不同位置,所以它们的引用是不同的。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    function getPersonInfo(one, two, three) {
    console.log(one);
    console.log(two);
    console.log(three);
    }
    const person = "Lydia";
    const age = 21;
    getPersonInfo`${person} is ${age} years old`;
    * ["", "is", "years old"] Lydia 21
    * 第一个参数'${person} is ${age} years old'.split('$') =》 ["", "{person} is ", "{age} years old"]
eval
  • eval会为字符串传递的代码求值。 如果它是一个表达式,它会计算表达式
    1
    const sum = eval("10*10+5"); // 105
对象键
  • 所有对象键(不包括Symbols)都会被存储为字符串,即使你没有给定字符串类型的键
  • 拓展
    • 如果对象有两个具有相同名称的键,则将替换前面的键。它仍将处于最开始的位置,但具有最后指定的值。
    • JavaScript全局执行上下文为你创建了两个东西:全局对象和this关键字.
    • 基本执行上下文是全局执行上下文:它是代码中随处可访问的内容。
    • 对象键自动转换为字符串,它变成了[object Object]
    • JavaScript只有原始类型和对象,原始类型是boolean,null,undefined,bigint,number,string和symbol。
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      const obj = { 1: "a", 2: "b", 3: "c" };
      const set = new Set([1, 2, 3, 4, 5]);

      obj.hasOwnProperty("1"); // true
      obj.hasOwnProperty(1); // true
      set.has("1"); // false
      set.has(1); // true

      const obj = { a: "one", b: "two", a: "three" };
      console.log(obj); // { a: "three", b: "two" }

      const a = {};
      const b = { key: "b" };
      const c = { key: "c" };

      a[b] = 123;
      a[c] = 456;

      console.log(a[b]); // 456
continue 声明终止当前循环或标记循环的当前迭代中的语句执行,并在下一次迭代时继续执行循环
1
2
3
4
5
6
7
8
9
let text = '';
for (let i = 0; i < 10; i++) {
if (i === 3) {
continue;
}
text = text + i;
}
console.log(text);
// expected output: "012456789"