文章目录
- 前言
- js实现push方法
- js实现订阅发布
- 手写防抖节流
- 手写reduce方法
- 后言
前言
hello world欢迎来到前端的新世界
😜当前文章系列专栏:前端面试
🐱👓博主在前端领域还有很多知识和技术需要掌握,正在不断努力填补技术短板。(如果出现错误,感谢大家指出)🌹
💖感谢大家支持!您的观看就是作者创作的动力
js实现push方法
let Arr = [1, 2, 3];
Array.prototype.push = function (...items) { // 通过Array.prototype.push的这个属性我们定义的方法顶替
const len = this.length; // 当前数组的长度
const itemCount = items.length; // 值的长度
for (let i = 0; i < itemCount; i++) { // 把每一个值都进行循环
this[len + i] = items[i]; // 把当前数组长度+i,i是循环的我们要添加的itemCount的长度的循环,第一个是1到我们数组的最长的长度根据我们的数组的特性,根据没有的索引进行添加值来操作,然后从而实现push添加
}
this.length = len + itemCount; // 更新数组长度
return this.length; // 返回数组更新长度
}
Arr.push(99) // 调用方法
console.log(Arr) // 查看数组调用后的后果
- 这里的this代表的当前的数组也就是下图中的这里,arr这里。
- 然后通过重新获取我们数组的长度(因为我们在循环添加数组的新属性的时候,我们的数组添加的过程中是用的 this[len + i] = items[i] 这种形式;
JavaScript 中的数组是一种特殊的对象,可以动态地添加属性(也就是索引)。当你使用一个不存在的索引访问或修改数组时,JavaScript 会自动将它作为一个新的属性添加到数组对象上,并为其赋予相应的值。
) - 然后就是值 我们传入值的长度
- 然后就是循环 这里大家应该懂吧,就是用let 声明一个i 然后循环条件就是i<传入值的长度的时候,我们的i++
- 循环的内容使用this[当前数组长度 + i] = 传入的值[i]
- 然后循环完后,是通过this.length 来确定我们当前数组的长度,当前数组长度 + 我们传入的数组的长度,就是我们当前数组长度
- 然后 返回最终我们的数组长度
js实现订阅发布
//
// 定义一个主题类 Subject
class Subject {
constructor() {
this.observers = []; // 初始化观察者数组
}
// 添加观察者
addObserver(observer){
this.observers.push(observer); // 将新的观察者添加到观察者数组中
}
// 删除观察者
removeObserver(observer){
this.observers = this.observers.filter(obs => obs !== observer); // 通过过滤将特定的观察者从数组中移除
}
// 状态变化通知观察者
notify(data){
this.observers.forEach(observer => {
observer.update(data); // 遍历观察者数组,调用每个观察者的 update 方法
});
}
}
// 定义一个观察者类 Observer
class Observer {
update(data){
console.log(`数据:${data}`); // 当接收到主题状态变化通知时,执行 update 方法来处理数据
}
}
const subject = new Subject(); // 创建一个主题实例
const observerOne = new Observer(); // 创建第一个观察者实例
const observerTwo = new Observer(); // 创建第二个观察者实例
subject.addObserver(observerOne); // 将第一个观察者添加到主题的观察者数组中
subject.addObserver(observerTwo); // 将第二个观察者添加到主题的观察者数组中
subject.removeObserver(observerTwo); // 从主题的观察者数组中移除第二个观察者
subject.notify("hello word lpz"); // 主题状态发生变化,通知所有的观察者进行更新处理
手写防抖节流
// 节流函数
function throttle(fn, delay) {
let timer = null; // 设置一个初始值为 null 的定时器变量
let lastTime = 0; // 这里的 lastTime 变量用于记录上一次执行函数的时间戳
return function(...args) { // 返回一个新的函数
const now = performance.now(); // 获取当前时间戳
const remainingTime = delay - (now - lastTime); // 计算距离上次执行函数剩余的时间
if (remainingTime <= 0) { // 如果剩余时间小于等于 0,则立即执行函数
if (timer) { // 如果存在已经设置的定时器,则清除它
clearTimeout(timer);
timer = null;
}
fn(...args); // 执行函数
lastTime = now; // 更新上一次执行函数的时间戳
} else if (!timer) { // 如果剩余时间大于 0,且不存在已经设置的定时器,则设置定时器
timer = setTimeout(() => { // 延迟剩余时间后执行函数
fn(...args);
lastTime = performance.now(); // 更新上一次执行函数的时间戳
timer = null; // 清空定时器变量
}, remainingTime);
}
};
}
function handle() {
console.log("触发");
}
let fn = throttle(handle, 2000); // 使用节流函数包装 handle 函数
fn(); // 第一次执行
// 监听滚动事件,在滚动过程中多次触发函数
window.addEventListener("scroll", fn);
手写reduce方法
Array.prototype.reduce = function(callback, initialValue) {
// 首先判断数组是否为空,并且判断回调函数是否为函数类型
if (this.length === 0 && typeof callback !== 'function') {
throw new TypeError('Array is empty and callback is not a function');
}
let accumulator = initialValue === undefined ? this[0] : initialValue; // 初始化累加器的值
for (let i = initialValue === undefined ? 1 : 0; i < this.length; i++) { // 从初始值开始迭代数组
accumulator = callback(accumulator, this[i], i, this); // 调用回调函数进行累加器值的更新
}
return accumulator; // 返回最终累加器的值
};
// 测试
const array = [1, 2, 3, 4, 5];
const sum = array.reduce((acc, cur) => acc + cur, 0);
console.log(sum); // 输出 15,即 1 + 2 + 3 + 4 + 5 的和
后言
创作不易,要是本文章对广大读者有那么一点点帮助 不妨三连支持一下,您的鼓励就是博主创作的动力