/**
* 柯里化函数
*/
const _curry = (...args) => {
let params = args
const addFn = (...args2) => {
params = params.concat(args2)
return addFn
}
addFn.valueOf = () => {
return params.reduce((pre, cur) => {
return pre + cur
}, 0)
}
return addFn
}
/**
* 手写apply apply(thisArg, [argsArray])
* @param {*} context
* @param {*} args
*/
Function.prototype._apply = function(context, args){
context = context || globalThis
const uniqueId = Symbol()
context[uniqueId] = this
const result = context[uniqueId](...args)
delete context[uniqueId]
return result
}
/**
* 手写call call(thisArg, arg1, arg2, ...)
* @param {*} context
* @param {...any} args
*/
Function.prototype._call = function (context, ...args){
context = context || globalThis
const uniqueId = Symbol()
context[uniqueId] = this
const result = context[uniqueId](...args)
delete context[uniqueId]
return result
}
/**
* 手写bind bind(thisArg, arg1, arg2, ...)
* @param {*} context
* @param {...any} args
*/
Function.prototype._bind = function (context, ...args){
const _this = this
return function (...newArgs) {
return _this.call(context, [...args, ...newArgs])
}
}
/**
* 防抖
* 触发事件后一定事件内未操作完成操作,反则重新设置事件
* @param { } fn
* @param {*} wait
*/
function _debounce(fn, wait){
let timer
return () => {
clearTimeout(timer)
setTimeout(() => {
fn()
timer = null
}, wait);
}
}
/**
* 节流
* 每间隔时间输出一次
* @param {*} fn
* @param {*} wait
*/
function _throttle(fn, wait){
let timer
return () => {
if(timer) return
setTimeout(() => {
fn()
timer = null
}, wait);
}
}
/**
* 深拷贝
* @param {*} obj
*/
const _deepClone = (obj) => {
if(typeof obj !== 'object' || typeof obj === null){
return obj
}
let copyObj
if(obj instanceof Set){
copyObj = new Set([...obj])
}else if(obj instanceof Map){
copyObj = new Map([...Map])
}else if(Array.isArray(obj)){
copyObj = []
for (let index = 0; index < obj.length; index++) {
copyObj.push(_deepClone(obj[index]))
}
}else{
copyObj = {}
// 返回由目标对象自身的属性键组成的数组
Reflect.ownKeys(obj).forEach(key => {
copyObj[key] = _deepClone(obj[key])
})
}
return copyObj
}
/**
* 手写promise
*/
class _Promise {
constructor(executor) {
// 初始化状态和结果
this.state = 'pending'; // 'pending', 'fulfilled', 'rejected'
this.value = undefined;
this.reason = undefined;
this.onFulfilledCallbacks = [];
this.onRejectedCallbacks = [];
// 执行传入的执行器函数
try {
executor(this.resolve.bind(this), this.reject.bind(this));
} catch (e) {
reject(e);
}
}
// 处理 resolve 逻辑
resolve(value) {
if (this.state === 'pending') {
this.state = 'fulfilled';
this.value = value;
// 为了执行延时队列中的任务
this.onFulfilledCallbacks.forEach(callback => callback(value));
}
}
// 处理 reject 逻辑
reject(reason) {
if (this.state === 'pending') {
this.state = 'rejected';
this.reason = reason;
this.onRejectedCallbacks.forEach(callback => callback(reason));
}
}
// 添加 then 处理逻辑
then(onFulfilled, onRejected) {
// 使用默认值防止没有提供回调函数的情况
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value;
onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason; };
return new _Promise((resolve, reject) => {
// 处理状态为 fulfilled 的情况
if (this.state === 'fulfilled') {
setTimeout(() => {
try {
const result = onFulfilled(this.value);
resolve(result);
} catch (e) {
reject(e);
}
}, 0);
}
// 处理状态为 rejected 的情况
if (this.state === 'rejected') {
setTimeout(() => {
try {
const result = onRejected(this.reason);
resolve(result);
} catch (e) {
reject(e);
}
}, 0);
}
// 处理状态为 pending 的情况
if (this.state === 'pending') {
this.onFulfilledCallbacks.push(() => {
setTimeout(() => {
try {
const result = onFulfilled(this.value);
resolve(result);
} catch (e) {
reject(e);
}
}, 0);
});
this.onRejectedCallbacks.push(() => {
setTimeout(() => {
try {
const result = onRejected(this.reason);
resolve(result);
} catch (e) {
reject(e);
}
}, 0);
});
}
});
}
}
/**
* 应用-观察者模式
*/
class _Observable{
constructor(initData){
this._data = initData
this._observers = []
// 创建代理
this.proxy = new Proxy(this._data, {
get: (target, prop) => {
console.log(`${prop} 被读取`);
return Reflect.get(target, prop)
},
set: (target, prop, value) => {
// 属性被修改时触发
console.log(`${prop} => ${value}`);
const result = Reflect.set(target, prop, value)
this.notifyObservers()
return result
}
})
}
// 通知所有观察者
notifyObservers() {
this._observers.forEach(observer => observer(this._data))
}
// 添加订阅者
subscribe(observer){
this._observers.push(observer)
console.log('_observers', this._observers);
}
// 移除订阅者
unsubscribe(observer){
this._observers = this._observers.filter(obs => obs !== observer)
}
}
const observable = new _Observable({name: 'Y'})
observable.subscribe(data => {
console.log('通知订阅者数据变动', data);
})
observable.proxy.name = 'C'
手写es6函数 常用函数
于 2024-05-05 22:18:38 首次发布