防抖
查看答案
js
function debounce(fn, delay) {
let timer = null;
return function () {
if (timer) clearTimeout(timer);
timer = setTimeout(() => {
fn.apply(this, arguments);
}, delay);
};
}节流
查看答案
js
function throttle(fn, delay) {
let starTime = 0;
return function () {
let nowTime = Date.now();
if (nowTime - starTime >= delay) {
starTime = Date.now();
fn.apply(this, arguments);
}
};
}实现 promise
查看答案
js
class MyPromise {
constructor(executor) {
this.status = "pending";
this.value = null;
this.reason = null;
this.fulfilledCallbacks = [];
this.rejectedCallbacks = [];
const resolve = (value) => {
if (this.status !== "pending") return;
this.status = "fulfilled";
this.value = value;
this.fulfilledCallbacks.forEach((fn) => fn(value));
};
const reject = (reason) => {
if (this.status !== "pending") return;
this.status = "rejected";
this.reason = reason;
this.rejectedCallbacks.forEach((fn) => fn(reason));
};
try {
executor(resolve, reject);
} catch (error) {
reject(error);
}
}
then(onFulfilled, onRejected) {
return new MyPromise((resolve, reject) => {
if (this.status === "fulfilled") {
setTimeout(() => {
try {
const result = onFulfilled(this.value);
resolve(result);
} catch (error) {
reject(error);
}
});
} else if (this.status === "rejected") {
setTimeout(() => {
try {
const result = onRejected(this.reason);
reject(result);
} catch (error) {
reject(error);
}
});
} else {
this.fulfilledCallbacks.push((val) => {
try {
const result = onFulfilled(val);
resolve(result);
} catch (error) {
reject(error);
}
});
this.rejectedCallbacks.push((val) => {
try {
const result = onRejected(val);
reject(result);
} catch (error) {
reject(error);
}
});
}
});
}
}手写深拷贝
查看答案
js
function deepClone(obj, hash = new WeakMap()) {
if (obj === undefined || obj === null || typeof obj !== "object") return obj;
if (obj instanceof Date) {
return new Date(obj);
}
if (obj instanceof RegExp) {
return new RegExp(obj);
}
if (hash.get(obj)) {
return hash.get(obj);
}
let newObj = Array.isArray(obj) ? [] : {};
hash.set(obj, newObj);
Object.keys(obj).forEach((key) => {
newObj[key] = deepClone(obj[key], hash);
});
return newObj;
}手写 new 操作符
查看答案
js
function myNew(fn, ...args) {
let obj = {};
obj.__proto__ = fn.prototype;
const result = fn.apply(obj, args);
return result instanceof Object ? result : obj;
}函数柯里化
查看答案
js
function curry(fn) {
if (typeof fn !== "function") return;
return function curried(...args) {
if (args.length >= fn.length) {
return fn.apply(this, args);
} else {
return function (...args2) {
return curried.apply(this, args.concat(args2));
};
}
};
}将对象数组转化为树结构
js
const items = [
{ id: 1, name: "Item 1", parentId: null },
{ id: 2, name: "Item 1.1", parentId: 1 },
{ id: 3, name: "Item 1.2", parentId: 1 },
{ id: 4, name: "Item 2", parentId: null },
{ id: 5, name: "Item 2.1", parentId: 4 },
];查看答案
js
function arrToTree(arr) {
const result = [];
const map = new Map();
arr.forEach((item) => {
map.set(item.id, { ...item, children: [] });
});
arr.forEach((item) => {
if (item.parentId === null) {
result.push(map.get(item.id));
} else {
map.get(item.parentId).children.push(map.get(item.id));
}
});
return result;
}发布-订阅模式
查看答案
js
class EventEmitter {
constructor() {
this.events = {};
}
on(eventName, callback) {
if (this.events[eventName]) {
this.events[eventName].push(callback);
} else {
this.events[eventName] = [callback];
}
}
emit(eventName, ...args) {
if (!this.events[eventName]) return;
this.events[eventName].forEach((fn) => fn(...args));
}
off(eventName, callback) {
if (!this.events[eventName]) return;
this.events[eventName] = this.events[eventName].filter(
(fn) => fn !== callback
);
}
}手写 vue
查看答案
js
class Dep {
constructor() {
this.subs = [];
}
depend() {
if (Dep.target && !this.subs.includes(Dep.target)) {
this.subs.push(Dep.target);
}
}
notify() {
this.subs.forEach((sub) => sub.update());
}
}
Dep.target = null;
class Watcher {
constructor(fn) {
this.fn = fn;
this.get();
}
get() {
Dep.target = this;
this.fn();
Dep.target = null;
}
update() {
this.get();
}
}
function observe(data) {
Object.keys(data).forEach((key) => {
let value = data[key];
let dep = new Dep();
Object.defineProperty(data, key, {
get() {
dep.depend();
return value;
},
set(newValue) {
value = newValue;
dep.notify();
},
});
});
}
const data = { name: "Harris", age: 26 };
observe(data);
new Watcher(() => {
console.log("视图更新:", data.name);
});
data.name = "whxrr";实现斐波那契数列
查看答案
js
function fibonacci(n) {
if (n <= 1) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
}js
function fibonacci(n, memo = {}) {
if (n <= 1) return n;
if (memo[n]) return memo[n];
memo[n] = fibonacci(n - 1, memo) + fibonacci(n - 2, memo);
return memo[n];
}字符串出现的不重复最长长度
查看答案
js
function longestUniqueSubstring(str) {
let seen = new Set();
let left = 0;
let maxLength = 0;
for (let right = 0; right < str.length; right++) {
while (seen.has(str[right])) {
seen.delete(str[left]);
left++;
}
seen.add(str[right]);
maxLength = Math.max(maxLength, right - left + 1);
}
return maxLength;
}Promise 实现最大并发数
查看答案
js
function limitConcurrency(tasks, max) {
let current = 0;
let index = 0;
const result = [];
return new Promise((resolve, reject) => {
function runNext() {
if (index === tasks.length && current === 0) {
return resolve(result);
}
while (current < max && index < tasks.length) {
const i = index++;
const task = tasks[i];
current++;
task()
.then((res) => {
result[i] = res;
})
.catch((err) => (result[i] = err))
.finally(() => {
current--;
runNext();
});
}
}
runNext();
});
}
