compose函数
function compose(...fn) {
if (!fn.length) return (v) => v;
if (fn.length === 1) return fn[0];
return fn.reduce(
(pre, cur) =>
(...args) =>
pre(cur(...args))
);
}
寄生组合继承
function Parent(name) {
this.name = name;
this.say = () => {
console.log(111);
};
}
Parent.prototype.play = () => {
console.log(222);
};
function Children(name) {
Parent.call(this);
this.name = name;
}
Children.prototype = Object.create(Parent.prototype);
Children.prototype.constructor = Children;
深拷贝
function deepCopy(obj,map = new WeakMap()){
if(!(obj instanceof Object))return obj
if(map.has(obj))return obj
const res = new obj.constructor()
map.set(obj,null)
for(const key in obj){
if(Object.prototype.hasOwnProperty.call(obj,key)){
res[key] = deepCopy(obj[key],map)
}
}
return res
}
const obj = [1,2,3,[1,2,3,[1,2,3]]]
console.log(deepCopy(obj))
instanceof
function myInstanceof(left, right) {
let proto = Object.getPrototypeOf(left),
prototype = right.prototype;
while (true) {
if (!proto) return false;
if (proto === prototype) return true;
proto = Object.getPrototypeOf(proto);
}
}
function myInstanceof(left, right) {
while (true) {
if (left === null) {
return false;
}
if (left.__proto__ === right.prototype) {
return true;
}
left = left.__proto__;
}
}
new操作符
function myNew(Func, ...args) {
const instance = {};
if (Func.prototype) {
Object.setPrototypeOf(instance, Func.prototype)
}
const res = Func.apply(instance, args)
if (typeof res === "function" || (typeof res === "object" && res !== null)) {
return res
}
return instance
}
function Person(name) {
this.name = name
}
Person.prototype.sayName = function() {
console.log(`My name is ${this.name}`)
}
const me = myNew(Person, 'Jack')
me.sayName()
console.log(me)
数组扁平化
function flatter(arr) {
if (!arr.length) return;
return arr.reduce(
(pre, cur) =>
Array.isArray(cur) ? [...pre, ...flatter(cur)] : [...pre, cur],
[]
);
}
function flatter(arr) {
if (!arr.length) return;
while (arr.some((item) => Array.isArray(item))) {
arr = [].concat(...arr);
}
return arr;
}
对象扁平方法
function isObject(val) {
return typeof val === "object" && val !== null;
}
function flatten(obj) {
if (!isObject(obj)) {
return;
}
let res = {};
const dfs = (cur, prefix) => {
if (isObject(cur)) {
if (Array.isArray(cur)) {
cur.forEach((item, index) => {
dfs(item, `${prefix}[${index}]`);
});
} else {
for (let k in cur) {
dfs(cur[k], `${prefix}${prefix ? "." : ""}${k}`);
}
}
} else {
res[prefix] = cur;
}
};
dfs(obj, "");
return res;
}
flatten();
列表转树
function listToTree(data) {
let temp = {};
let treeData = [];
for (let i = 0; i < data.length; i++) {
temp[data[i].id] = data[i];
}
for (let i in temp) {
if (+temp[i].parentId != 0) {
if (!temp[temp[i].parentId].children) {
temp[temp[i].parentId].children = [];
}
temp[temp[i].parentId].children.push(temp[i]);
} else {
treeData.push(temp[i]);
}
}
return treeData;
}
树转列表
function treeToList(data) {
let res = [];
const dfs = (tree) => {
tree.forEach((item) => {
if (item.children) {
dfs(item.children);
delete item.children;
}
res.push(item);
});
};
dfs(data);
return res;
}
Dom To Json
function dom2Json(domtree) {
let obj = {}
obj.name = domtree.tagName
obj.children = []
domtree.childNodes.forEach((child) => obj.children.push(dom2Json(child)))
return obj
}
Json To 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) {
Object.keys(vnode.attrs).forEach((key) => {
const value = vnode.attrs[key];
dom.setAttribute(key, value);
});
}
vnode.children.forEach((child) => dom.appendChild(_render(child)));
return dom;
}
类数组转化为数组
const arrayLike=document.querySelectorAll('div')
[...arrayLike]
Array.from(arrayLike)
Array.prototype.slice.call(arrayLike)
Array.apply(null, arrayLike)
Array.prototype.concat.apply([], arrayLike)
大数相加
function add(a ,b){
let maxLength = Math.max(a.length, b.length);
a = a.padStart(maxLength , 0);
b = b.padStart(maxLength , 0);
let t = 0;
let f = 0;
let sum = "";
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;
}
AJAX数据请求
const getJSON = function (url) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open("GET", url, false);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.onreadystatechange = function () {
if (xhr.readyState !== 4) return;
if (xhr.status === 200 || xhr.status === 304) {
resolve(xhr.responseText);
} else {
reject(new Error(xhr.responseText));
}
};
xhr.send();
});
};
函数柯里化,实现add(1)(2)(3)()=6 add(1,2,3)(4)()=10
function add(...args) {
let allArgs = [...args]
function fn(...newArgs) {
allArgs = [...allArgs, ...newArgs]
return fn
}
fn.toString = function () {
if (!allArgs.length) {
return
}
return allArgs.reduce((sum, cur) => sum + cur)
}
return fn
}
LRU算法
class LRUCache {
constructor(capacity) {
this.secretKey = new Map();
this.capacity = capacity;
}
get(key) {
if (this.secretKey.has(key)) {
let tempValue = this.secretKey.get(key);
this.secretKey.delete(key);
this.secretKey.set(key, tempValue);
return tempValue;
} else return -1;
}
put(key, value) {
if (this.secretKey.has(key)) {
this.secretKey.delete(key);
this.secretKey.set(key, value);
}
else if (this.secretKey.size < this.capacity) {
this.secretKey.set(key, value);
}
else {
this.secretKey.set(key, value);
this.secretKey.delete(this.secretKey.keys().next().value);
}
}
}
实现sleep函数
const sleep = time => {
return new Promise(resolve => setTimeout(resolve,time))
}
sleep(1000).then(()=>{
console.log(1)
})
function sleep(callback,time) {
if(typeof callback === 'function')
setTimeout(callback,time)
}
function output(){
console.log(1);
}
sleep(output,1000);
实现千分位分隔符
var str = "100000000000",
reg = /(?=(\B\d{3})+$)/g;
str.replace(reg, ",")
防抖
function debounce(func, ms = 1000) {
let timer;
return function (...args) {
if (timer) {
clearTimeout(timer)
}
timer = setTimeout(() => {
func.apply(this, args)
}, ms)
}
}
const task = () => { console.log('run task') }
const debounceTask = debounce(task, 1000)
window.addEventListener('scroll', debounceTask)
节流
function throttle(func, ms = 1000) {
let canRun = true
return function (...args) {
if (!canRun) return
canRun = false
setTimeout(() => {
func.apply(this, args)
canRun = true
}, ms)
}
}
const task = () => { console.log('run task') }
const throttleTask = throttle(task, 1000)
window.addEventListener('scroll', throttleTask)