专业技能
- 样式作用域冲突:CSS-in-JS 通过为每个组件生成唯一的类名,确保样式只作用于当前组件,避免了全局样式冲突的问题
- 动态样式难以实现:JavaScript 中根据组件的状态或属性动态生成样式
- 样式复用性差:CSS-in-JS 利用 JavaScript 的模块化机制
1.掌握盒⼦模型,Flex响应式布局和BFC等问题
盒⼦模型
Flex布局
媒体查询
结合Handleresize.ts监听设备
BFC
2.掌握原型链,异步,事件循环和闭包等问题
原型链
异步
JS是一门
单线程
的语言,这是因为它运行在浏览器的渲染主线程中
,而渲染主线程只有一个。而渲染主线程承担着诸多的工作,渲染页面、执行JS都在其中运行
。如果使用同步的方式
,就极有可能导致主线程产生阻塞(卡顿、TBT)
,从而导致消息队列
中的很多其他任务无法得到执行。这样一来,一方面会导致繁忙的主线程白白的消耗时间,另一方面导致页面无法及时更新,给用户造成卡死
现
象。所以浏览器采用异步的方式来避免。具体做法是当某些任务发生时
,比如计时器、网络、事件监听,主线程将任务交给其他线程去处理
,自身立即结束任务的执行,转而执行后续代码
。当其他线程完成时,将事先传递的回调函数
包装成任务,加入到消息队列的末尾排队
,等待主线程调度执行。在这种异步模式下,浏览器永不阻塞,从而最大限度的保证了单线程的流畅运行。
class Promise {
static resolve(value) {
if (value instanceof Promise) {
return value;
}
return new Promise((resolve) => {
resolve(value);
});
}
static reject(reason) {
return new Promise((_, reject) => {
reject(reason);
});
}
static race(promises) {
return new Promise((resolve, reject) => {
promises.forEach((promise) => {
Promise.resolve(promise).then(resolve, reject);
});
});
}
static all(promises) {
return new Promise((resolve, reject) => {
const results = [];
let completedCount = 0;
if (promises.length === 0) {
resolve(results);
return;
}
promises.forEach((promise, index) => {
Promise.resolve(promise).then(
(value) => {
results[index] = value;
completedCount++;
if (completedCount === promises.length) {
resolve(results);
}
},
(reason) => {
reject(reason);
}
);
});
});
}
constructor(executor) {
// 状态
this.status = "pending";
// 成功结果
this.value = undefined;
// 失败原因
this.reason = undefined;
// 成功回调函数队列
this.onResolvedCallbacks = [];
// 失败回调函数队列
this.onRejectedCallbacks = [];
let resolve = (value) => {
if (this.status === "pending") {
// 新的值需要是 Promise,则递归解析
if (value instanceof Promise) {
return value.then(resolve, reject);
}
this.status = "fulfilled";
this.value = value;
// 异步执行所有成功回调
this.onResolvedCallbacks.forEach((fn) => fn());
}
};
let reject = (reason) => {
if (this.status === "pending") {
this.status = "rejected";
this.reason = reason;
// 异步执行所有失败回调
this.onRejectedCallbacks.forEach((fn) => fn());
}
};
// 执行器本身错误,直接 reject
try {
executor(resolve, reject);
} catch (error) {
reject(error);
}
}
then(onFulfilled, onRejected) {
onFulfilled = typeof onFulfilled === "function" ? onFulfilled : (value) => value;
onRejected = typeof onRejected === "function" ? onRejected : (reason) => {
throw reason;
};
let context = this;
return new Promise((resolve, reject) => {
function handleOnFulfilled() {
try {
const result = onFulfilled(context.value);
if (result instanceof Promise) {
result.then(resolve, reject);
} else {
resolve(result);
}
} catch (error) {
reject(error);
}
}
function handleOnRejected() {
try {
const result = onRejected(context.reason);
if (result instanceof Promise) {
result.then(resolve, reject);
} else {
resolve(result);
}
} catch (error) {
reject(error);
}
}
if (this.status === "fulfilled") {
setTimeout(() => {
handleOnFulfilled();
}, 0);
}
if (this.status === "rejected") {
setTimeout(() => {
handleOnRejected();
}, 0);
}
// 当状态为 pending 时
if (this.status === "pending") {
// onFulfilled 传入到成功数组
this.onResolvedCallbacks.push(handleOnFulfilled);
// onRejected 传入到失败数组
this.onRejectedCallbacks.push(handleOnRejected);
}
});
}
catch(onRejected) {
return this.then(null, onRejected);
}
finally(onFinally) {
return this.then(
(value) => Promise.resolve(onFinally()).then(() => value),
(reason) => Promise.resolve(onFinally()).then(() => {
throw reason;
})
);
}
}
事件循环
class EventLoop {
constructor() {
this.callStack = [];
this.taskQueue = [];
this.microtaskQueue = [];
}
run() {
while (this.callStack.length > 0 || this.taskQueue.length > 0 || this.microtaskQueue.length > 0) {
// 执行同步代码
while (this.callStack.length > 0) {
const task = this.callStack.pop();
task();
}
// 执行微任务
while (this.microtaskQueue.length > 0) {
const microtask = this.microtaskQueue.shift();
microtask();
}
// 执行宏任务
if (this.taskQueue.length > 0) {
const task = this.taskQueue.shift();
task();
}
}
}
}
闭包
const counterModule = (function() {
let count = 0; // 私有变量
return {
increment: function() {
count++;
console.log(count);
},
reset: function() {
count = 0;
console.log('计数器已重置');
}
};
})();