前端溜圈群技术小题复盘-第二周

187 阅读2分钟

前端溜圈群技术小题复盘-第二周

每周工作日会出一道小题,一周五题,周六分享会复盘结束后本人会将问题与答案整理出来~方便群内小伙伴复习。

这里只整理简短的解析与答案(但是我会在每周复盘中详细讲解以及扩展),具体内容不懂的话可以谷歌或者私我,当然还是建议大家多多思考多多讨论。

每天第一名正确回答并解释完整的同学可以获得群主的奖励红包

第一天

  • 整个 script 为一个宏任务
  • await 让出线程,其语法糖可以简单理解为
async function f() {
  await p;
  fn();
}

=>

function f() {
  return Promise.resolve(p).then(() => {
    fn();
  })
}

p 立即执行,fn 为 Promise resolve后的回调,推入微任务队列

  • setTimeout 为宏任务,promise 为微任务
  • 每次 Loop 后,取出一个宏任务执行,然后清空微任务

答案:

script start async1 start async2 promise1 script end async1 end promise2 setTimeout

第二天

核心代码为 var a = b = 3,其等同于

b = 3;
var a = b;
  • b 全局声明
  • var a 为 IIFE 内的局部变量
  • typeof 不存在的变量为 undefined

答案:

undefined

number

第三天

  • 第一个 fn 虽然在 obj 中调用,但是实际执行时是在 window 环境(因为并不是 obj.fn )
  • Arguments 为类数组,执行其中方法,this 指向该 arguments

答案: 10 2

第四天

  • 使用 Class 并返回实例来实现链式调用
  • 用队列来维护事件执行顺序
  • 使用延时器来模拟 Sleep
  • 注意绑定 this
class ManagerClass {
  constructor(name) {
    this.taskList = [];
    console.log(`Hi I am ${name}`);
    setTimeout(() => this.next(), 0);
  }

  sleepFirst(time) {
    let fn = () => {
      console.log(`Sleep ${time}s...`);
      setTimeout(() => {
        this.next();
      }, time * 1000);
    }

    this.taskList.unshift(fn);
    return this;
  }

  sleep(time) {
    let fn = () => {
      console.log(`Sleep ${time}s...`);
      setTimeout(() => {
        this.next();
      }, time * 1000);
    }

    this.taskList.push(fn);
    return this;
  }

  eat(name) {
    let fn = () => {
      console.log(`I am eating ${name}`);
      this.next();
    }

    this.taskList.push(fn);
    return this;
  }

  next() {
    let fn = this.taskList.shift();

    fn && fn();
  }
}

function Manager(name) {
  return new ManagerClass(name);
}

Manager('AddOne').eat('breakfast').eat('lunch').sleepFirst(2).sleep(1).eat('dinner');

第五天

CSS

请用一种简单方案实现如图效果

第一种:绘制三角形后定位到左上角

第二种:渐变

background:linear-gradient(135deg, #F3AC3C 100px, #0B2429 0);

JS

使用 requestAnimationFrame 实现一个 setInterval

  • 注意 requestAnimationFrame 的使用方法即可
function setInterval(func, interval) {
  let last = +new Date();
  let timer;

  const loop = () => {
    let now = +new Date();
    timer = window.requestAnimationFrame(loop);
    if(now - last >= interval) {
      last = now;
      func(timer);
    }
  }

  timer = window.requestAnimationFrame(loop);

  return timer;
}

let count = 0;
setInterval(timer => {
  console.log(1);
  count++;
  if(count === 5) cancelAnimationFrame(timer);
}, 1000)