画出浏览器渲染示意图

- 追问1:引起无效回流的原因有哪些/怎样避免无效回流;
- 追问2:你平时是如何优化前端性能的;
- 追问3:页面白屏的成因与防治;
- 追问4:渲染算不算异步?优先级如何?
请画出Animal-Person-Student三级继承关系到原型链示意图

- 追问:class的extends起什么作用?背后到底干了写什么?
- 追问:父类的方法实现子类不满意时怎么办?
- 追问:既想使用父类实现,又想扩展出一些新内容,怎么办?
- 追问:super(name)和super.sayHello()有何区别?
- 追问:new 关键词做了些什么?
- 追问:OOP的所有问题
请画出HTTP协议的缓存流程示意图

- 追问:Etag和Last-Modified冲突时,该返数据还是304?
- 追问:造成Etag未变但Last-Modified变了,为什么会形成这种现象?
- 追问:用户的刷新动作对缓存有什么影响?
事件循环示意图

- 追问:同一时间:定时器到钟了,用户点击了,网络数据回来了,回调先后顺序
- 追问:多个异步任务如何调度?
- 追问:如何实现多个异步任务的串行有关联/无关联,并行有关联/无关联;
- 追问:几乎所有异步问题...
手写防抖函数debounce
function debounce(fn, delay) {
let timer = null
return function (...args) {
if (timer) {
clearTimeout(timer)
timer = null
}
timer = setTimeout(() => {
fn.apply(null, args)
timer = null
}, delay)
}
}
手写节流函数throttle
function throttle(fn, delay) {
let lock = false;
return function (...args) {
if (!lock) {
fn.apply(null, args);
lock = true;
setTimeout(() => {
lock = false;
}, delay);
}
};
}
手写深拷贝deepCopy
function deepCopy(data){
switch (true) {
case typeof(data)!=="object" && typeof(data)!=="function":
return data;
case typeof(data)==="function":
return data;
case Array.isArray(data):
const arr = []
for(let i=0;i<data.length;i++){
arr[i] = deepCopy(data[i])
}
return arr;
case typeof(data)==="object":
const obj = {}
for(let key in data){
obj[key] = deepCopy(data[key])
}
return obj;
default:
return data;
}
}
手写Promise链求5的阶乘
function multiply(a, b, callback) {
setTimeout(() => callback(a * b), 500);
}
function mulPromise(a, b) {
return new Promise((resolve, reject) =>
multiply.apply(null, [a, b, (ret) => resolve(ret)])
);
}
mulPromise(2, 3)
.them(res => mulPromise(res, 4)
.them(res => mulPromise(res, 5)
.them(res => console.log('最终结果', res)
手写async-await求5的阶乘
function multiply(a, b, callback) {
setTimeout(() => {
Math.random() > 0.5 ? callback(a * b) : callback(-1);
}, 500);
}
function mulPromise(a, b) {
return new Promise((resolve, reject) => {
multiply.apply(null, [ a,b, (ret) => {
ret === -1 ? reject("云端计算失败") : resolve(ret);
},
]);
});
}
async function test() {
try {
let res = await mulPromise(2, 3)
res = await mulPromise(res, 4)
res = await mulPromise(res, 5)
console.log(res)
} catch(err) {
console.log('err=', err)
}
}
test()
手写数组的批处理API(即入参为一个函数的API)demo各一个
const arr = [1, 2, 3, 4, 5]
遍历:
forEach((item, index) => { console.log(item) )
映射:
map((item) => {Math.pow(item, 2)})
过滤:
filter((item) => {item % 3 == 0})
所有:
every((item) => {item % 3 == 0})
有一个:
some((item) => {item % 3 == 0})
第一个:
find((item) => {item % 3 == 0})
累加:reduce((pv, cv) => {pv + cv})
在100基础上累加:reduce((pv, cv) => {pv + cv}, 100)
手写Promise三大静态调度API demo各一个
function promiseAll() {
Promise.all([
Promise.resolve(3),
Promise.reject(42),
new Promise(
(resolve, reject) => setTimeout(() => resolve("foo"), 5000)
),
])
.then((values) => console.log("values=", values))
.catch((err) => console.log("err=", err));
}
function promiseAllSettled() {
Promise.allSettled([
Promise.resolve(3),
Promise.resolve(42),
new Promise(
(resolve, reject) =>
setTimeout(() => reject("我妈不让我和坏孩子玩"), 5000)
),
])
.then((values) => console.log("values=", values))
}
function promiseRace() {
Promise.race([
new Promise((resolve, reject) => {
setTimeout(resolve, 3000, "one");
}),
new Promise((resolve, reject) => {
setTimeout(reject, 10000, "two");
}),
new Promise(
(resolve, reject) =>
setTimeout(() => reject("我妈不让我和坏孩子玩"), 5000)
),
])
.then((value) => console.log("value=", value))
.catch((err) => console.log("err=", err));
}
扩展数组实现arr.countItems,以对象形式返回每个元素分别出现多少次
const arr = [2, 5, 6, 6, 4, 3, 3, 4, 5, 2]
Array.prototype.countItems = function () {
let obj = {}
this.forEach(item => {
if (!obj[item]) {
obj[item] = 1
} else {
obj[item]++
}
})
return obj
}
console.log(arr.countItems())
手写Animal-Person-Student三级继承关系(含静态与覆写)原型链实现
手写Animal-Person-Student三级继承关系(含静态与覆写)class实现
手写多参柯里化高阶函数curry
手写同步函数的Promise化高阶函数promisify
手写管道高阶函数pipe
手写组合高阶函数compose
手写MyMap
手写MySet
前端核心笔试题(持续更新)具体看这里