一定要坚持下去的前端面试题--面经

247 阅读2分钟

微软

基础

  1. 联合类型|和枚举各有什么优缺点
  2. 虚拟DOM优缺点
  3. 大table优化

手写代码题

  1. 设计一个结构描述一段html结构,并实现一个runnr方法,将其渲染出来
{
    <ul>
        <li>1</li>
        2
        <li>
            <p>3</p>
        </li>
    </ul>
}
  1. 代码执行顺序
const myPromise = () => Promise.resolve("I have resolved!");
function firstFunction() {
  myPromise().then((res) => console.log(res + "in first"));
  console.log("first");
}
async function secondFunction() {
  console.log("aync");
  console.log(await myPromise());
  console.log("second");
}
secondFunction();
firstFunction();
  1. 打印出给定dom元素中所有子元素标签名,需要有尖括号和缩进,例如
<div>
    <p>
        <a></a>
    </p>
    <span>
    </span>
</div>
function printAllDom(dom) {
  let res = "";
  let level = 1;

  function build(dom, level) {
    if (!dom) return;
    const tagName = dom.tagName;
    const children = dom.children;

    res += `${new Array(level).fill("").join(" ")}<${tagName}>\n`;

    Array.from(children).forEach((child) => {
      build(child, level + 1);
    });

    res += `${new Array(level).fill("").join(" ")}</${tagName}>\n`;
  }

  build(dom, level);

  return res;
}
  1. 数字转EXCEL列,eg. 703 => 'AAA'
function transformToString(num) {
  const numA = "A".charCodeAt();

  const len = 26;

  let res = "";

  while (num > 0) {
    let m = num % len === 0 ? len : num % len;
    res = String.fromCharCode(m + numA - 1) + res;
    num = (num - m) / 26;
  }

  return res;
}

transformToString(703);
  1. 题目要求:实现html方法,将template模板渲染到相应dom节点中。 最终实现的效果为:

image.png

<!DOCTYPE html>
<html>
  <head>
    <title>Parcel Sandbox</title>
    <meta charset="UTF-8" />
  </head>

  <body>
    <h1>Case1</h1>
    <div id="case1"></div>
    <hr />
    <h1>Case2</h1>
    <div id="case2"></div>

    <script src="src/index.js"></script>
  </body>
</html>
function render(root, template, data) {
  const _data = Object.assign(data, { rerender });
  function rerender() {
    root.innerHTML = template(_data);
  }
  rerender();
}

const template1 = html`
  <div>
    <h1>${(x) => x.title}</h1>
    <p>${(x) => x.description}</p>
  </div>
`;

const template2 = html`
  <div>
    <h1>${(x) => x.title}</h1>
    <button ${(x) => x.update}>${(x) => x.number}</button>
    <button ${(x) => x.reset}>reset</button>
  </div>
`;

render(document.getElementById("case1"), template1, {
  title: "Paragraph",
  description: "Hi, template!",
});

render(document.getElementById("case2"), template2, {
  title: "Counter",
  number: 0,
  update: {
    type: "click",
    runner() {
      this.number = this.number + 1;
    },
  },
  reset: {
    type: "click",
    runner() {
      this.number = 0;
    },
  },
});

function html(strings, ...args) {

    return (x) => {

        return strings.reduce((prev, next, idx) => {

            prev += `${args[idx - 1] ? args[idx - 1](x) : ""}${next}`;

            return prev;

        });

    };

}

备注:带标签的模板字符串

function a (strs, ...args) {
    console.log('strs', strs);
    console.log('args', args)
}

const name = 'huahua';
const age = 12;

a`name:${name}, age:${age}`

输入结果:

strs ['name: ', ', age:', '', raw: Array(3)]
args ['huahua', 12]

可以看到,标签模板字符串的标签函数的第一个参数是由原始的字符串由占位字符串分割而成的字符串组成的数组,剩下的参数则是对应占位符的值。

字节

基础

  1. width = height = 0, borderWidth = 5,每条边颜色不一样,是什么效果
  2. 函数提升和变量提升
var getName;
function getName() {
    console.log('function getName')
}

getName = function () {
    console.log('var getName')
}

getName();
function Foo() {
    this.name = 'foo';
}

new Foo() 与 new Foo
  1. typescript中interface和type的区别

手写代码

  1. 将数组中所有零移到最后
  2. 代码执行顺序
new Promise((resolve, reject) => {
    throw new Error();
    console.log(1);
}).then(() => {}, () => {console.log(1)})
.catch(() => console.log(3))
.then(() => {console.log(4)})
  1. 实现Task
const t = new Task()

t
    .log(1)
    .log(2)
    .sleep(3)
    .sleep(2)
    .log(4)
// 带延时功能的链式调用
class Task {
    queue = Promise.resolve();
    log(num) {
        this.queue = this.queue.then(() => {
            console.log(num);
        })
        return this;
    }

    sleep(delay) {
        this.queue = this.queue.then(() => {
            return new Promise((resolve) => {
                setTimeout(() => {
                    resolve();
                }, delay * 1000);
            })
        })
        return this;
    }
}

const t= new Task()
t.log(1).sleep(2).log(2).sleep(3).log(3)