1、实现compose函数
function fn1(x) {
return x + 1
}
function fn2(x) {
return x + 2
}
function fn3(x) {
return x + 3
}
function fn4(x) {
return x + 4
}
function compose(...arg) {
let arr = arg
return arr.reduce((prev, next) => {
return (num) => {
return prev(next(num))
}
})
}
let a = compose(fn1, fn2, fn3, fn4)
console.log(a(1))
2、基于setTimeout实现setInterval
function test() {
console.log('3333333')
}
function mySetInterval(fn, delay = 1000) {
let timer = null
let interval = () => {
fn()
timer = setTimeout(interval, delay)
}
timer = setTimeout(interval, delay)
return {
cancle: () => clearTimeout(timer)
}
}
mySetInterval(test)
3、setInterval模拟实现setTimeout
function test() {
console.log('3333333333')
}
function mySetTimeout(fn, delay = 1000) {
let timer = null
timer = setInterval(() => {
clearInterval(timer)
fn()
}, delay)
}
mySetTimeout(test)
4、实现发布订阅模式
class EventEmitter{
constructor() {
this.cache = {}
}
on(type, fn) {
if(!this.cache[type]) this.cache[type] = []
this.cache[type].push(fn)
}
off(type, fn) {
if(!this.cache[type]) return
if(!fn) {
this.cache[type] = []
}else {
this.cache[type] = this.cache[type].filter(item => item !== fn)
}
}
emit(type, ...arg) {
if(!this.cache[type]) return
this.cache[type].forEach(item => item(...arg))
}
once(type, fn) {
const fnNew = () => {
fn()
this.off(type, fnNew)
}
this.on(type, fnNew)
}
}
5、数组去重(方法很多,这里只写一种)
function uniqueArr(arr) {
return [...new Set(arr)]
}
console.log(uniqueArr([1,2,3,5,5,6,6]))
6、数组扁平化
const isHasArr = (arr) => arr.some(item => Array.isArray(item))
function flatter(arr, count) {
let i = 0
while(isHasArr(arr) && (!count || i < count)) {
arr = [].concat(...arr)
i++
}
return arr
}
console.log(flatter([1,2,3,[1,2,[2, [5]]]]))
7、寄生组合式继承
function Parent(name) {
this.name = name
this.say = function () {
console.log(`我是${this.name}, 今年${this.age}岁`)
}
}
function Child(name, age) {
Parent.call(this, name)
this.age = age
}
Child.prototype = Object.create(Parent.prototype)
Child.prototype.constructor = Child
const child = new Child('张三', 18)
child.say()
8、实现一个promise调度器
class Scheduler{
constructor(limit) {
this.limit = limit
this.taskQueue = []
this.startTaskCount = 0
}
add(time, info) {
const fn = () => {
return new Promise((rsolve, reject) => {
setTimeout(() => {
console.log(info)
rsolve()
}, time)
})
}
this.taskQueue.push(fn)
}
startTask() {
for(let i = 0; i < this.limit; i++) {
this.request()
}
}
request() {
if(this.startTaskCount >= this.limit || this.taskQueue.length < 1) return
this.startTaskCount++
this.taskQueue.shift()().then(() => {
this.startTaskCount--
this.request()
})
}
}
const scheduler = new Scheduler(2)
scheduler.add(1000, "1")
scheduler.add(500, "2")
scheduler.add(300, "3")
scheduler.add(400, "4")
scheduler.startTask()
9、实现new操作符
function myNew(Fn, ...arg) {
let obj = Object.create(null)
obj.__proto__ = Fn.prototype
let result = Fn.call(obj, ...arg)
return (typeof result === 'object' && result !== null) || typeof result === 'function' ? result : obj
}
10、深度克隆
function deepClone(obj) {
if(typeof obj !== 'object' || obj === null) {
return obj
}else if(obj instanceof Set) {
let set = new Set()
obj.forEach(item => {
set.add(deepClone(item))
})
return set
}else if(obj instanceof Map) {
let map = new Map()
obj.forEach((item, key) => {
map.set(key, deepClone(item))
})
return map
}else if(obj instanceof RegExp) {
return new RegExp(obj)
}else if(obj instanceof Date) {
return new Date(obj)
}else {
let cloneObj = Array.isArray(obj) ? [] : {}4
for(let key in obj) {
if(obj.hasOwnProperty(key)) {
cloneObj[key] = deepClone(obj[key])
}
}
return cloneObj
}
}
11、实现instanceof
function myInstanceof(child, parent) {
while(child) {
if(child.__proto__ === parent.prototype) return true
child = child.__proto__
}
return false
}
function Test() {}
let test = new Test()
console.log(myInstanceof(test, Test))
12、函数柯里化
function fn(a, b, c, d) {
return a + b + c + d
}
function currying(fn, ...arg) {
let args = [...arg]
const result = (...Arg) => {
args = [...args, ...Arg]
if(args.length >= fn.length) {
return fn(...args)
}
return result
}
return result
}
let fn1 = currying(fn, 1,2)
console.log(fn1(3,5, 7))
13、实现LazyMan函数
function LazyMan(name) {
return new _LazyMan(name)
}
class _LazyMan{
constructor(name) {
this.name = name
this.taskQueue = []
const fn = () => {
console.log(`Hi! This is ${this.name}`)
this.next()
}
this.taskQueue.push(fn)
Promise.resolve().then(() => {
this.next()
})
}
next() {
if(!this.taskQueue.length) return
this.taskQueue.shift()()
}
eat(food) {
const fn = () => {
console.log(`Eat ${food}~`)
this.next()
}
this.taskQueue.push(fn)
return this
}
sleep(s) {
this.timeFn(10, true)
return this
}
sleepFirst(s) {
this.timeFn(5, false)
return this
}
timeFn(s, flag) {
const fn = () => {
setTimeout(() => {
console.log(`Wake Up after ${s}秒`)
this.next()
}, s*1000)
}
if(flag) {
this.taskQueue.push(fn)
}else {
this.taskQueue.unshift(fn)
}
}
}
14、版本排序的方法
function MySort(arr) {
arr.sort((a, b) => {
let i = 0
let arr1 = a.split('.')
let arr2 = b.split('.')
while(true) {
let s1 = arr1[i]
let s2 = arr2[i]
i++
if(s1 === undefined || s2 === undefined) return arr2.length - arr1.length
if(s1 === s2) continue
return s2 - s1
}
})
return arr
}
15、LRU缓存
class LRUCache{
constructor(limit) {
this.limit = limit
this.map = new Map()
}
get(key) {
if(!this.map.has(key)) return -1
let tempValue = this.map.get(key)
this.map.delete(key)
this.map.set(key, tempValue)
return tempValue
}
put(key, value) {
if(this.map.has(key)) {
this.map.delete(key)
this.map.set(key, value)
}else {
if(this.map.size === this.limit) {
this.map.delete(this.map.keys().next().value)
this.map.set(key, value)
}else {
this.map.set(key, value)
}
}
}
}
16、实现一个add方法
function add(...arg) {
let args = [...arg]
const fn = (...Arg) => {
args = [...args, ...Arg]
return fn
}
fn.toString = () => {
if(!args.length) return
return args.reduce((prev, curr) => prev + curr, 0)
}
return fn
}
console.log(add(1,2,3)(4)()==10)
17、动态规划求解硬币找零
function coinChange(coins, amount) {
if(coins.length < 1) return -1
let dp = []
dp[0] = 0
let len = coins.length
for(let i = 1; i <= amount; i++){
dp[i] = Infinity
for(let j = 0; j < len; j++) {
if(i >= coins[j]) {
dp[i] = Math.min(dp[i], dp[i - coins[j]] + 1)
}
}
}
if(dp[amount] === Infinity) return -1
return dp[amount]
};
console.log(coinChange([1, 2, 5], 11))
18、请实现DOM2JSON一个函数,可以把一个DOM节点输出JSON格式
function dom2Json(domtree) {
let obj = {}
obj.name = domtree.tagName
obj.children = []
domtree.children.forEach(item => obj.children.push(dom2Json(item)))
return obj
}
19、实现json格式数据转dom
function _render(vnode) {
if(typeof vnode === 'number') vnode = String(vnode)
if(typeof vnode === 'string') return document.createTextNode(vnode)
const dom = document.createElement(vnode.tag)
if(vnode.attrs) {
let keys = Object.keys(vnode.attrs)
keys.forEach(key => dom.setAttribute(key, vnode.attrs[key]))
}
if(vnode.children && Array.isArray(vnode.children)) {
vnode.children.forEach(item => dom.appendChild(_render(item)))
}
return dom
}
20、实现模板字符串解析
let template = "我是{{name}},年龄{{age}},性别{{sex}}";
let data = {
name: "张三",
age: 18,
sex: '男'
};
function render(template, data) {
const computed = template.replace(/\{\{(\w+)\}\}/g, function (match, key) {
return data[key]
})
return computed
}
console.log(render(template, data))
21、对象扁平化
const isObject = (obj) => typeof obj === 'object' && obj !== null
const isArray = (arr) => Array.isArray(arr)
function flatten(obj) {
let newObj = {}
const fn = (value, str) => {
if(!isObject(value)) {
let newStr = str + ''
newObj[newStr] = value
return
}
for(let key in value) {
if(isArray(value)) {
fn(value[key], str + `[${key}]`)
}else {
fn(value[key], str === '' ? str + `${key}` : str + `.${key}`)
}
}
}
fn(obj, '')
return newObj
}
const obj = {
a: {
b: 1,
c: 2,
d: {e: 5}
},
b: [1, 3, {a: 2, b: 3}],
c: 3
}
console.log(flatten(obj))
22、列表转成树
function listToTree(data) {
let map = {}
let tree = []
data.forEach(item => map[item.id] = item)
data.forEach(item => {
if(map[item.parentId]) {
(map[item.parentId].children || (map[item.parentId].children = [])).push(item)
}else {
tree.push(item)
}
})
return tree
}
let arr = [
{
id: 1,
text: '节点1',
parentId: 0
},
{
id: 2,
text: '节点1_1',
parentId: 1
}
]
console.log(listToTree(arr))
23、树形结构转成列表
function treeToList(data) {
let arr = []
const fn = (tree) => {
tree.forEach(item => {
arr.push(item)
if(item.children) {
fn(item.children)
delete item.children
}
})
}
fn(treeData)
return arr
}
let treeData = [
{
id: 1,
text: '节点1',
parentId: 0,
children: [
{
id:2,
text: '节点1_1',
parentId:1
}
]
}
]
console.log(treeToList(treeData))
24、大数相加
function add(a, b) {
let maxLength = Math.max(a.length, b.length)
let t = 0
let f = 0
let sum = ''
a = a.padStart(maxLength, 0)
b = b.padStart(maxLength, 0)
for(let i = maxLength - 1; i >= 0; i--) {
t = parseInt(a[i]) + parseInt(b[i]) + f
f = Math.floor(t / 10)
sum = (t % 10) + sum
}
if(f !== 0) {
sum = '' + f + sum
}
return sum
}
let a = "9007199254740991"
let b = "1234567899999999999"
console.log(add(a, b))
25、两数相加
function intersect(num1, num2) {
const len1 = num1.length
const len2 = num2.length
num1.sort((a, b) => a - b)
num2.sort((a, b) => a - b)
let res = []
let i = 0
let j = 0
while(i < len1 && j < len2) {
if(num1[i] === num2[j]) {
res.push(num1[i])
i++
j++
}else if(num1[i] < num2[j]) {
i++
}else {
j++
}
}
return res
}
let m1 = [4, 9, 5]
let m2 = [9, 4, 9, 8, 4]
let n1 = [1, 2, 2, 1]
let n2 = [2, 2]
console.log(intersect(m1, m2))
console.log(intersect(n1, n2))