![](https://s2.loli.net/2022/10/09/31kvp8HRJuoBCfc.jpg)
各种手写源码
async/await 实现
实现一个双向数据绑定
Array.isArray 实现
promise 实现
防抖
文章可见防抖与节流
饭都
javascript
function debounce(func, wait, flag) {
let timer = null;
return function (...args) {
clearTimeout(timer);
if (!timer && flag) {
func.apply(this, args)
} else {
timer = setTimeout(() => {
func.apply(this, args)
}, wait)
}
}
}
节流
javascript
function throttle(func, wait) {
let pre,
timer = null;
if (Date.now() - pre > wait) {
clearTimeout(timer);
timer = null;
pre = Date.now()
func.apply(this, args)
} else if (!timer) {
timer = setTimeout(() => {
func.apply(this, args)
}, wait)
}
}
new
文章可看new 做了什么
ES5 版本:
javascript
function new2(Constructor, ...args) {
let obj = Object.create(null);
obj.__proto__ = Constructor.prototype;
let result = Constructor.apply(obj, args);
return typeof result === 'object' ? result : obj;
}
ES3 版本:
javascript
function new3() {
let obj = {},
Constructor = Array.prototype.shift.call(arguments)
var F = function(){}
F.prototype = Constructor.prototype
obj = new F()
var result = Constructor.apply(obj, arguments)
returb typeof result === 'object' ? result : obj
}
Object.create
javascript
function create(obj) {
function F() {}
F.prototype = obj;
return new F()
}
深拷贝
文章可看拷贝的密码
javascript
function deepClone(source, storage = new WeakMap()) {
// 针对基本数据类型
if (typeof source !== 'object' || source === null) {
return source
}
// 是否是日期
if (source.constructor === Date) {
return new Date(source)
}
// 是否是正则
if (source.constructor === RegExp) {
return new RegExp(source)
}
// 是否是数组
let target = source instanceof Array ? [] : {}
// 循环引用 返回存储的引用数据
if (storage.has(source)) return storage.get(source)
// 开辟存储空间设置临时存储值
storage.set(source, target)
// 是否包含 Symbol 类型
let isSymbol = Object.getOwnPropertySymbols(source)
// 包含 Symbol 类型
if (isSymbol.length) {
isSymbol.forEach((item) => {
if (typeof source[item] === 'object') {
target[item] = deepClone(source[item], storage);
return
}
target[item] = source[item]
})
}
// 不包含 Symbol
for(let key in source) {
if (source.hasOwnProperty(key)) {
target[key] = typeof source[key] === 'object' ? deepClone(sourcep[key], storage) : source[key]
}
}
return target;
}
instanceof
文章可看instanceof——找祖籍
javascript
function myInstanceof(left, right) {
if (typeof left !== 'object' || left === null) return false;
let proto = Object.getPrototypeOf(left);
while (true) {
if (proto == null) return false;
if (proto == right.prototype) return true;
proto = Object.getPrototypeOf(proto);
}
}
call、apply、bind
call
javascript
function myCall(context = window, args) {
if (this === Function.prototype) {
return undefined;
}
let fn = Symbol()
context[fn] = this;
let result = context[fn](...args)
delete context[fn];
return result
}
apply
javascript
function myApply(context = window, args) {
if (this === Function.prototype){
return undefined
}
let fn = Symbol()
context[fn] = this;
let result;
if (Array.isArray(arg)){
result = context[fn](...args)
} else {
result = context[fn]()
}
delete context[fn]
return result
}
bind
javascript
function myBind(context, ...args1) {
if (this === Function.prototype) {
return new TypeError('Error')
}
const _this = this;
return function F(...args2) {
if (this instance F) {
return new _this(...args1, ...args2)
}
return _this.apply(context, args1.concat(args2))
}
}
reduce
柯里化
javascript
function curry(fn) {
return function curriedFn() {
var _args = Array.prototype.slice.call(arguments);
if (_args.length < fn.length) {
return function () {
var _args2 = Array.prototype.slice.call(arguments);
return curriedFn.apply(null, _args.concat(_args2));
};
}
return fn.apply(null, _args);
};
}
ES6 实现
javascript
function curry(fn) {
return function curriedFn(...args) {
if (args.length < fn.length) {
return function () {
return curriedFn(...args.concat(Array.from(arguments)));
};
}
return fn(...args);
};
}
发布订阅
javascript
class eventEmitter {
constructor() {
this.event = {}
}
on(type, callback) {
if (!this.event[type]) {
this.event[type] = [callback]
} else {
this.event[type].push(callback)
}
}
off(type, callback) {
if (!this.event[type]) {
return
}
this.event[type] = this.event[type].filter((item) => {
return item !== callback
})
}
emit(type, ...args) {
if (!this.event[type]) {
return
}
this.event[type].forEach((callback) => {
callback.apply(this, args)
})
}
once(type, callback) {
function f() {
callback()
this.off(type, f)
}
this.on(type, f)
}
}
示例:
javascript
const eventEmitter = new EventEmitter();
// 订阅事件
eventEmitter.on("公众号", (name) => {
console.log(`我订阅了${name}`)
})
// 发布事件
eventEmitter.emit('公众号', '随朱波流')