code

类型

isType

1
function isType(type){
2
return function (o){
3
return Object.prototype.toString.call(o)===`[object ${type}]`
4
}
5
}
Copied!

深拷贝

1
1.
2
JSON.parse(JSON.stringfy(obj));
3
4
2.
5
//WeakMap解决对象循环引用问题
6
function deepClone(obj, weakMap = new WeakMap()) {
7
if (!(obj instanceof Object)) return obj
8
var isArray = obj instanceof Array
9
var res = isArray ? [] : {}
10
if (!isArray) {
11
if (weakMap.get(obj)) return {}
12
weakMap.set(obj, {}.toString.call(obj))
13
}
14
for (var key in obj) {
15
if (obj.hasOwnProperty(key)) {
16
res[key] = deepClone(obj[key], weakMap)
17
}
18
}
19
return res
20
}
21
22
// 浅拷贝
23
function clone(obj) {
24
if (!(obj instanceof Object)) return obj
25
var res = obj instanceof Array ? [] : {}
26
for (var key in obj) {
27
if (obj.hasOwnProperty(key)) {
28
res[key] = obj[key]
29
}
30
}
31
return res
32
}
Copied!

防抖

1
function debounce(fn, delay) {
2
let timer;
3
return function (...args) {
4
const context = this;
5
clearTimeout(timer);
6
timer = setTimeout(fn.bind(context, ...args), delay);
7
};
8
}
Copied!

节流

1
function throttle(fn, time) {
2
let canCall = true;
3
4
return function (...args) {
5
if (!canCall) return;
6
canCall = false;
7
fn(...args);
8
setTimeout(() => {
9
canCall = true;
10
}, time);
11
};
12
}
Copied!

实现 new

1
function newObject() {
2
var obj = Object.create(null);
3
//去除参数里的构造函数
4
const Constructor = [].shift.call(arguments);
5
obj.__proto__ = Constructor.prototype;
6
Constructor.apply(obj, arguments);
7
return obj;
8
}
9
10
function factory(name, age) {
11
this.name = name;
12
this.age = age;
13
}
14
15
var obj = newObject(factory, "xjq", 23);
Copied!

实现 call

1
Function.prototype.call2 = function (context) {
2
// 首先要获取调用call的函数,用this可以获取
3
context.fn = this;
4
const obj = [].shift.call(arguments);
5
obj.fn(...arguments);
6
delete obj.fn;
7
};
Copied!

实现bind

1
Function.prototype.bind2 = function (o) {
2
const context = this
3
return function () {
4
const symbol = Symbol()
5
o[symbol] = context
6
o[symbol](...arguments)
7
delete o[symbol]
8
}
9
}
Copied!

实现 instanceof

1
function _instanceof(l, r) {
2
const f = r.prototype
3
while (true) {
4
if (l === f) {
5
return true
6
}
7
if (!l) {
8
return false
9
}
10
l = l.__proto__
11
}
12
}
Copied!

实现 Promise

1
function Promise(fn) {
2
this.state = 'pending'
3
this.value = null
4
this.callbacks = []
5
fn(this._resolve.bind(this), this._reject.bind(this))
6
}
7
8
Promise.prototype._resolve = function (value) {
9
if (this.state === 'pending') {
10
this.state = 'fullfilled'
11
this.value = value
12
this.callbacks.forEach((fn) => this._handle(fn))
13
}
14
}
15
16
Promise.prototype._reject = function (value) {
17
if (this.state === 'pending') {
18
this.state = 'rejected'
19
this.value = value
20
this.callbacks.forEach((fn) => this._handle(fn))
21
}
22
}
23
24
Promise.prototype._handle = function (callback) {
25
if (this.state === 'pending') {
26
this.callbacks.push(callback)
27
return
28
}
29
let cb = this.state === 'fullfilled' ? callback.onFullfilled : callback.onRejected
30
if (!cb) {
31
cb = this.state === 'fullfilled' ? callback.resolve : callback.reject
32
cb(this.value)
33
return
34
}
35
let ret
36
try {
37
ret = cb(this.value)
38
cb = this.state === 'fullfilled' ? callback.resolve : callback.reject
39
} catch (error) {
40
ret = error
41
cb = callback.reject
42
} finally {
43
cb(ret)
44
}
45
}
46
47
Promise.prototype.then = function (onFullfilled, onRejected) {
48
return new Promise((resolve, reject) => {
49
this._handle({
50
onFullfilled: onFullfilled || null,
51
onRejected: onRejected || null,
52
resolve,
53
reject,
54
})
55
})
56
}
57
58
Promise.prototype.catch = function (onError) {
59
return this.then(null, onError)
60
}
61
62
63
Promise.prototype.finally = function (onFinally) {
64
if (typeof onFinally !== 'function') return this.then()
65
let promise = this.constructor
66
return this.then(
67
(value) => promise.resolve(onFinally()).then(() => value),
68
(reason) =>
69
promise.resolve(onFinally()).then(() => {
70
throw reason
71
})
72
)
73
}
74
75
Promise.resolve = function (value) {
76
if (value && value instanceof Promise) {
77
return value
78
} else if (value && value instanceof Object && value.then instanceof Function) {
79
const then = value.then
80
return new Promise((resolve) => then(resolve))
81
} else {
82
return new Promise((resolve) => resolve(value))
83
}
84
}
85
86
Promise.reject = function (value) {
87
if (value && value instanceof Object && value.then instanceof Function) {
88
const then = value.then
89
return new Promise((resolve, reject) => then(reject))
90
} else {
91
return new Promise((resolve, reject) => reject(value))
92
}
93
}
94
95
Promise.all = function (promiseList) {
96
return new Promise((resolve, reject) => {
97
const resList = []
98
promiseList.forEach((p, index) => {
99
p.then(
100
(res) => {
101
resList[index] = res
102
if (resList.length === arr.length) {
103
resolve(resList)
104
}
105
},
106
(err) => reject(err)
107
)
108
})
109
})
110
}
111
112
Promise.race = function (promiseList) {
113
return new Promise((resolve, reject) => {
114
for (let i = 0; i < promiseList.length; i++) {
115
Promise.resolve(promiseList[i]).then(
116
(res) => {
117
resolve(res)
118
},
119
(err) => {
120
reject(err)
121
}
122
)
123
}
124
})
125
}
Copied!

实现 reduce

1
function _reduce(fn, initialValue) {
2
const arr = this
3
let i = 0
4
if (initialValue === undefined) {
5
initialValue = arr[0]
6
i++
7
}
8
for (; i < arr.length; i++) {
9
initialValue = fn(initialValue, arr[i], i)
10
}
11
return initialValue
12
}
13
Copied!

for of

1
function forOf(fn) {
2
const it = this[Symbol.iterator]()
3
while (true) {
4
const { value, done } = it.next()
5
if (done) break
6
fn(value)
7
}
8
}
9
10
const arr = [1, 2, 3, 4]
11
12
forOf.call(arr, (e) => {
13
console.log(e)
14
})
Copied!

jsonp

1
function jsonp({ url, callback }) {
2
const script = document.createElement('script')
3
script.src = url + '?cb=' + callback.name
4
document.body.appendChild(script)
5
}
6
7
function fn(data) {
8
console.log('data', data)
9
}
10
11
jsonp({
12
url: 'http://127.0.0.1:3000',
13
callback: fn,
14
})
15
16
// 后端返回的是javascript代码
17
// fn({a:1})
Copied!

柯里化函数

1
const add = (args) => args.reduce((a, b) => a + b, 0)
2
3
function currying(func) {
4
const args = []
5
return function result(...rest) {
6
if (rest.length) {
7
args.push(...rest)
8
return result
9
} else {
10
return func(args)
11
}
12
}
13
}
Copied!

响应式原理

Proxy

1
const app = document.querySelector('#app')
2
3
var data = {
4
t1: 't1',
5
t2: 't2',
6
t3: [1, 2],
7
t4: { a: 1, arr: [1, 2] },
8
}
9
10
function proxy(target, handler) {
11
Object.keys(target).forEach((key) => {
12
if (target[key] instanceof Array || target[key] instanceof Object) {
13
target[key] = proxy(target[key], handler)
14
}
15
})
16
return new Proxy(target, {
17
get: function (obj, key) {
18
return obj[key]
19
},
20
set: function (obj, key, newValue) {
21
obj[key] = newValue
22
handler()
23
return true
24
},
25
})
26
}
27
28
var dataProxy = proxy(data, update)
29
30
function update() {
31
const { t1, t2, t3, t4 } = dataProxy
32
document.getElementById('app').textContent = `t1:${t1},t2:${t2},t3:${t3.map((o) => o)},t4:${t4.arr.map((v) => v)}`
33
}
34
35
update()
Copied!

Object.defineProperty

1
const app = document.querySelector('#app')
2
3
var data = {
4
t1: 't1',
5
t2: 't2',
6
t4: { a: 1 },
7
}
8
9
function reactive(target, handler) {
10
Object.keys(target).forEach((key) => {
11
if (target[key] instanceof Object) {
12
reactive(target[key], handler)
13
} else {
14
let tar = target[key]
15
console.log(key, tar)
16
Object.defineProperty(target, key, {
17
get: function () {
18
return tar
19
},
20
set: function (newValue) {
21
if (tar !== newValue) {
22
tar = newValue
23
handler()
24
}
25
},
26
})
27
}
28
})
29
}
30
31
reactive(data, update)
32
33
function update() {
34
const { t1, t2, t4 } = data
35
document.getElementById('app').textContent = `t1:${t1},t2:${t2},t4:${t4.a}`
36
}
37
38
update()
39
Copied!

数组监听

1
function MyArray() {}
2
3
function clone(prototype) {
4
function F() {}
5
F.prototype = prototype
6
return new F()
7
}
8
9
function inherit(p, o) {
10
let prototype = clone(o.prototype)
11
prototype.constructor = o
12
p.prototype = prototype
13
}
14
15
inherit(MyArray, Array)
16
17
const _methodKey = ['push', 'pop', 'shift']
18
const _method = _methodKey.reduce((acc, cur) => {
19
acc[cur] = MyArray.prototype[cur]
20
return acc
21
}, {})
22
23
MyArray.prototype.push = function (params) {
24
this.update('push')
25
_method['push'].call(this, params)
26
}
27
28
MyArray.prototype.pop = function (params) {
29
this.update('pop')
30
_method['pop'].call(this, params)
31
}
32
33
MyArray.prototype.update = function (type) {
34
console.log(type)
35
}
36
37
const arr = new MyArray()
38
arr.push(3)
39
arr.pop()
40
arr.push(3)
41
42
console.log(arr)
43
Copied!

Event类实现

1
class Event {
2
constructor() {
3
this.event = {}
4
this.maxListener = 5
5
this.listenerCount = 0
6
}
7
on(type, fn) {
8
if (this.listenerCount >= this.maxListener) {
9
throw new Error('事件数量超限')
10
}
11
let hasEvent = !!this.event[type]
12
if (typeof fn === 'function') {
13
if (hasEvent) {
14
this.event[type].push(fn)
15
} else {
16
this.event[type] = [fn]
17
}
18
}
19
if (!hasEvent) this.listenerCount++
20
}
21
22
once(type, fn) {
23
const _this = this
24
function newFn() {
25
fn(...arguments)
26
_this.removeListener(type, newFn)
27
}
28
this.on(type, newFn)
29
}
30
31
emit(type, params) {
32
if (this.event[type]) {
33
this.event[type].forEach((fn) => fn(params))
34
}
35
}
36
37
setMaxListeners(count) {
38
this.maxListener = count
39
}
40
41
listeners(type) {
42
return this.event[type] || []
43
}
44
45
removeAllListener(type) {
46
this.event[type] = null
47
}
48
removeListener(type, listener) {
49
if (this.event[type]) {
50
this.event[type] = this.event[type].filter((fn) => listener !== fn)
51
}
52
}
53
54
addListener(type, fn) {
55
this.on(type, fn)
56
}
57
}
58
59
const e = new Event()
60
function a1() {
61
console.log('a1')
62
}
63
64
function a2() {
65
console.log('a2')
66
}
67
68
e.once('a', a1)
69
e.on('a', a2)
70
e.emit('a')
71
e.emit('a')
72
Copied!

并发限制的异步调度器

1
class Scheduler {
2
constructor() {
3
this.runQueue = []
4
this.queue = []
5
this.count = 2
6
}
7
8
addTask(task) {
9
this.queue.push(task)
10
return this.run()
11
}
12
13
run() {
14
if (this.runQueue.length < this.count && this.queue.length) {
15
const task = this.queue.shift()
16
const promise = task().then(() => {
17
this.runQueue.splice(this.runQueue.indexOf(promise), 1)
18
})
19
this.runQueue.push(promise)
20
return promise
21
} else {
22
return Promise.race(this.runQueue).then(() => this.run())
23
}
24
}
25
}
26
27
const timeout = (time) =>
28
new Promise((resolve) => {
29
setTimeout(resolve, time)
30
})
31
32
const scheduler = new Scheduler()
33
const addTask = (time, order) => {
34
scheduler
35
.addTask(() => timeout(time))
36
.then(() => {
37
console.log(order)
38
})
39
}
40
41
addTask(10000, '1')
42
addTask(5000, '2')
43
addTask(3000, '3')
44
addTask(4000, '4')
Copied!

实现 redux

实现

1
export function createStore(reducer, enhancer) {
2
let state = {}
3
let isDispatching = false
4
5
let listeners = []
6
7
if (typeof enhancer === "function") {
8
return enhancer(createStore)(reducer)
9
}
10
11
function getState() {
12
return state
13
}
14
15
function dispatch(action) {
16
if (typeof action.type === undefined) {
17
throw new Error("action has not type")
18
}
19
if (isDispatching) {
20
throw new Error("is dispatching")
21
}
22
23
try {
24
isDispatching = true
25
state = reducer(state, action)
26
console.log(state)
27
listeners.forEach((fn) => fn())
28
} catch (error) {
29
console.log(error)
30
isDispatching = false
31
}
32
}
33
34
function subscribe(listener) {
35
listeners.push(listener)
36
return listeners.filter((fn) => listener !== fn)
37
}
38
39
return {
40
getState,
41
dispatch,
42
subscribe,
43
}
44
}
45
46
export function dispatchBook(payload) {
47
return { type: "BOOK", payload }
48
}
49
50
export function reducerBook(state = {}, action) {
51
switch (action.type) {
52
case "BOOK":
53
return { ...state, name: action.payload }
54
}
55
}
56
57
export function bindActionCreators(actionCreators, dispatch) {
58
return Object.keys(actionCreators).reduce((acc, cur) => {
59
acc[cur] = function (...args) {
60
dispatch(actionCreators[cur](...args))
61
}
62
return acc
63
}, {})
64
}
65
66
export function combineReducers(reducers) {
67
return (state, action) => {
68
return Object.keys(reducers).reduce((acc, cur) => {
69
acc[cur] = reducers[cur](state[cur], action)
70
return acc
71
}, {})
72
}
73
}
74
75
export function applyMiddleware(middleWares) {
76
return (createStore) => (reducer) => {
77
let store = createStore(reducer)
78
let newDispatch = compose(middleWares.map((middleware) => middleware(store)))(store.dispatch)
79
return { ...store, dispatch: newDispatch }
80
}
81
}
82
83
export function compose(args) {
84
return args.reduce(
85
(acc, cur) =>
86
(...args) =>
87
acc(cur(...args))
88
)
89
}
90
Copied!

test

1
import { combineReducers, createStore, applyMiddleware, bindActionCreators } from "./index"
2
3
function reduxLogger(store) {
4
return (dispatch) => (action) => {
5
console.log(store.getState())
6
dispatch(action)
7
console.log(store.getState())
8
}
9
}
10
11
function reduxCustom(store) {
12
return (dispatch) => (action) => {
13
dispatch(action)
14
console.log("c", store.getState())
15
}
16
}
17
18
const mergeReducers = combineReducers({ book: reducerBook })
19
const store = createStore(mergeReducers, applyMiddleware([reduxCustom, reduxLogger]))
20
21
const actions = bindActionCreators({ dispatchBook }, store.dispatch)
22
23
store.subscribe(() => {
24
// console.log(11)
25
})
26
27
actions.dispatchBook("xxx")
28
Copied!

实现 react-redux

1
const { Component } = require("react");
2
const { bindActionCreators } = require("redux");
3
4
class Provider extends Component{
5
getChildContent(){
6
return {store:this.props.store}
7
}
8
render(){
9
return this.props.children
10
}
11
}
12
13
14
function connect(mapStateToProps,mapDispatchToProps){
15
return function(WrapperComponent){
16
class ProxyComponent extends Component{
17
constructor(props,context){
18
super(props,context)
19
this.store=context.store
20
this.state=mapStateToProps(this.store.getState())
21
}
22
23
render(){
24
let actions
25
if(typeof mapDispatchToProps==='function'){
26
actions=mapDispatchToProps(this.store.dispatch)
27
}else if(typeof mapDispatchToProps==='object'){
28
actions=bindActionCreators(mapDispatchToProps,this.store.dispatch)
29
}
30
return <WrapperComponent {...this.state} {...actions}/>
31
}
32
}
33
return ProxyComponent
34
}
35
}
Copied!

数组

乱序

扁平化

1
function flatten(arr) {
2
let res = []
3
arr.forEach((item) => {
4
if (Array.isArray(item)) {
5
res = [...res, flatten(item)]
6
} else {
7
res.push(item)
8
}
9
})
10
return res
11
}
Copied!

去重

1
1. Set
2
3
[...new Set[arr]]
4
5
2. 对象属性去重
6
function unique(arr) {
7
let len = arr.length
8
let res = []
9
let obj = {}
10
for (let i = 0; i < len; i++) {
11
if (!obj.hasOwnProperty(arr[i])) {
12
obj[arr[i]] = arr[i]
13
}
14
}
15
return Object.values(arr)
16
}
17
18
3. indexOf
19
function unique(arr) {
20
let res = []
21
for (let i = 0; i < arr.length; i++) {
22
if (res.indexOf(arr[i]) === -1) {
23
res.push(arr[i])
24
}
25
}
26
return res
27
}
28
Copied!

Ajax

1
function request({ method, url, data = null, config: { headers = {}, timeout = 60 * 1000, async = true } }) {
2
return new Promise((resolve, reject) => {
3
const xhr = new XMLHttpRequest()
4
xhr.open(method, url, async)
5
6
Object.entries(headers).forEach((headerArr) => {
7
xhr.setRequestHeader(headerArr[0], headerArr[1])
8
})
9
10
xhr.send(data)
11
xhr.timeout = timeout
12
xhr.ontimeout = () => {
13
reject()
14
}
15
16
xhr.onreadystatechange = () => {
17
if (xhr.readyState === 4) {
18
const status = xhr.status
19
if ((status >= 200 && status < 300) || status === 304) {
20
resolve(xhr.responseText)
21
} else {
22
reject()
23
}
24
}
25
}
26
})
27
}
28
29
request({ method: 'POST', url: 'http://127.0.0.1:3000', config: { timeout: 10 * 1000 } })
30
.then((res) => {
31
console.log(res)
32
})
33
.catch((err) => {
34
console.log(err)
35
})
36
Copied!

排序

稳定性:待排序的记录中,存在多个具有相同关键字的记录,经过排序后,这些记录的相对序列保持不变,则称算法是稳定的,否则是不稳定的

冒泡排序

1
function bubbleSort(arr) {
2
let len = arr.length
3
for (let i = 0; i < len - 1; i++) {
4
for (let j = 0; j < len - i; j++) {
5
if (arr[j] > arr[j + 1]) {
6
let temp = arr[j]
7
arr[j] = arr[j + 1]
8
arr[j + 1] = temp
9
}
10
}
11
}
12
return arr
13
}
Copied!

快排

1
function quickSort(arr) {
2
_quickSort(arr, 0, arr.length - 1)
3
}
4
function _quickSort(arr, l, r) {
5
if (l > r) return
6
7
let left = l,
8
right = r
9
10
let base = arr[left]
11
let temp
12
while (l != r) {
13
while