防抖 与 节流

1
2
3
4
5
6
7
8
9
10
11
12
function debounce(fn, timeout){
var timers
return function() {
if (timers) {
clearTimeout(timers)
}
let args = arguments;
timers = setTimeout(() => {
fn.apply(this, args)
}, timeout)
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
function throttle(fn, timeout) {
var isCan = true
return function() {
if (!isCan) {
return
}
isCan = false
let args = arguments;
setTimeout(()=>{
fn.apply(this, args)
isCan = true
}, timeout)
}
}

深拷贝

1
2
3
4
5
6
7
8
9
10
11
12
13
function deeCopy(obj) {
if(typeof obj === 'object') {
let newObj = Array.isArray(obj)?[]:{}
for(let key in obj) {
if(obj.hasOwnProperty(key)) {
newObj[key] = deeCopy(obj[key])
}
}
return newObj
} else {
return obj
}
}

函数柯里化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
function myCurrying() {
let arg1 = Array.prototype.slice.call(arguments)
let sum = eval(arg1.join('+'))
function inner() {
let arg2 = Array.prototype.slice.call(arguments)
return myCurrying(sum+eval(arg2.join('+')))
}
// 若要省略后缀myval 可以试试toString (浏览器里可以直接出值)
inner.myval = function () {
return sum
}
return inner
}

// console.log(myCurrying(1, 2)(3)(1,5,9,8).myval())

// 或
function curry() {
let args = [].slice.call(arguments)
function inner() {
let arg2 = [].slice.call(arguments)
if (arg2.length==0) {
return eval(args.join('+'))
} else {
return curry(eval(args.join('+')) + eval(arg2.join('+')))
}
}
return inner
}

// console.log(curry(3,4)(2,5)())

数组reduce函数

1
2
3
4
5
6
7
8
9
10
11
12
13
Array.prototype.reduce = function (fn, base = 0) {
for(let i=0,len=this.length;i<len;i++) {
base = fn(base, this[i])
}
return base
}

let array = [1,2,1,3,4]

let result = array.reduce(function(pre, item){
return pre+item
}, 9)
// console.log(result)

多维数组转一维数组

1
2
3
4
5
6
7
8
9
10
11
// 多维数组转一维
let arr = [1,2,3,[4,5,[6]]]

let newArr = JSON.stringify(arr).replace(/\[|\]/g, '').split(',').map(parseInt) // !!! [ 1, NaN, NaN, NaN, NaN, NaN ]

let newArr1 = arr.toString().split(',').map(Number) // [ 1, 2, 3, 4, 5, 6 ]

console.log(newArr)

// ES6
console.log(arr.flat(Infinity))

Promise all函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Promise.all = function (pArr) {
return new Promise((resolve, reject)=>{
let result = [], count = 0
if (pArr.length==0) {
resolve(result)
} else {
for(let i=0,len=pArr.length;i<len;i++) {
Promise.solve(pArr[i]).then((res)=>{
result[i] = res
count++
if(count>=pArr.length) {
resolve(result)
}
}, (error) => {
reject(error)
})
}
}
})
}

js事件模型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
class EventEmitter {
constructor () {
this._events = Object.create(null)
}
on(event, callback) {
if(this._events[event]) {
this._events[event].push(callback)
} else {
this._events[event] = [callback]
}
}
off (event, callback) {
if (this._events[event]) {
let index = this._events[event].indexOf(callback)
if(index>-1) {
this._events[event].splice(index, 1)
}
}
}
emit(event) {
let args = Array.prototype.slice.call(arguments, 1)
for(let i=0,len=this._events[event].length;i<len;i++) {
this._events[event][i].apply(this, args)
}
}
once(event, callback) {
let only = function(){
callback.apply(this, arguments)
this.off(event, only)
}
this.on(event, only)
}
}

手写Ajax

1
2
3
4
5
6
7
8
9
10
11
12
13
function myAjax(type, url, data, callback) {
let xhr = new XMLHttpRequest()
xhr.open(type, url)
if (type=='post') {
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded')
}
xhr.send(data)
xhr.onreadystatechange = function () {
if (xhr.readyState==4&&xhr.status==200) {
callback(xhr.responseText)
}
}
}

实现jsonp

1
2
3
4
5
6
7
8
9
10
11
12
13
function myJsonp(url, callback) {

var cbFuncName = 'my_json_cb_' + Math.random().toString().replace('.','');
let script = document.createElement('script')
script.src = url + '?callback=' + cbFuncName

document.body.appendChild(script)

window[cbFuncName] = function(data) {
callback(data)
document.body.removeChild(script)
}
}

二叉树遍历

1
2
3
4
5
6
7
8
9
10
11
// 先序遍历(深度优先)递归法
function preOrder (node) {
if (node==null) {
return
}
console.log(node.val)
preOrder(node.left)
preOrder(node.right)
}

// 中序后序同理

链表反转

1
2
3
4
5
6
7
8
9
10
11
12
// 链表反转
function reverseLink (node) {
let end = null, temp
while(node!=null) {
temp = node.next
node.next = end

end = node
node = temp
}
return end
}