// url的queryString转成对象
function queryStr2Obj(url) {
const query = {};
const search = url.split('?')[1];
if (!search) {
return {}
}
search.split('&').forEach(item => {
let [ key, value] = item.replace('=', ':').split(':');
query[key] = decodeURIComponent(value);
});
return query;
}
// list数组转tree数组
const currentArray = [
{id:"01", name: "张大大", pid:"", job: "项目经理"},
{id:"02", name: "小亮", pid:"01", job: "产品leader"},
{id:"03", name: "小美", pid:"01", job: "UIleader"},
{id:"04", name: "老马", pid:"01", job: "技术leader"},
{id:"05", name: "老王", pid:"01", job: "测试leader"},
{id:"06", name: "老李", pid:"01", job: "运维leader"},
{id:"07", name: "小丽", pid:"02", job: "产品经理"},
{id:"08", name: "大光", pid:"02", job: "产品经理"},
{id:"09", name: "小高", pid:"03", job: "UI设计师"},
{id:"10", name: "小刘", pid:"04", job: "前端工程师"},
{id:"11", name: "小华", pid:"04", job: "后端工程师"},
{id:"12", name: "小李", pid:"04", job: "后端工程师"},
{id:"13", name: "小赵", pid:"05", job: "测试工程师"},
{id:"14", name: "小强", pid:"05", job: "测试工程师"},
{id:"15", name: "小涛", pid:"06", job: "运维工程师"}
];
function list2tree(list, pid){
let children = list.filter(item => item.pid == pid);
return children.map(item => {
item.children = list2tree(list, item.id);
return item;
})
}
// tree数组转list数组
function tree2list(tree){
const list = [], queue = [...tree];
while(queue.length){
let { children, ...node } = queue.shift();
if(children){
queue.push(...children)
}
list.push(node)
}
return list;
}
// 多维数组,每每元素组合,不重复
/*
* 如: arr = [[1,2],[3,4]] => combination(arr) => [[1,3],[1,4],[2,3],[2,4]]
*/
function combination(arr){
const ary = [];
const store = [];
const fn = function (i = 0){
for(let j = 0; j<arr[i].length;j++){
if(i < arr.length - 1){
store[i] = arr[i][j];
fn(i+1)
}else{
ary.push([...store, arr[i][j]])
}
}
}
fn();
return ary;
}
// 函数柯里化(思路:递归收集参数,参数刚好时调用原函数)
function curry(fn, args = []){
return (...arg) => {
let _arg = args.concat(arg)
if(_arg.length != fn.length){
return curry(fn, _arg)
}else{
return fn(..._arg)
}
}
}
// 节流
function throttle(fn, delay) {
// 重置定时器
let timer = null;
// 返回闭包函数
return function () {
// 记录事件参数
let args = arguments;
// 如果定时器为空
if (!timer) {
// 开启定时器
timer = setTimeout(() => {
// 执行函数
fn.apply(this, args);
// 函数执行完毕后重置定时器
timer = null;
}, delay);
}
}
}
// 防抖
function debounce(fn, delay = 500) {
// timer是一个定时器
let timer = null;
// 返回一个闭包函数,用闭包保存timer确保其不会销毁,重复点击会清理上一次的定时器
return function () {
// 保存事件参数,防止fn函数需要事件参数里的数据
let arg = arguments;
// 调用一次就清除上一次的定时器
clearTimeout(timer);
// 开启这一次的定时器
timer = setTimeout(() => {
// 若不改变this指向,则会指向fn定义环境
fn.apply(this, arg);
}, delay)
}
}
// call
function mycall(that, ...args){
that = that == null ? window : new Object(that)
that.fn = this;
that.fn(...args);
delete that.fn;
}
Function.prototype.mycall = mycall
// apply
function myapply(that, args){
that = that == null ? window : new Object(that)
that.fn = this;
that.fn(...args);
delete that.fn;
}
Function.prototype.myapply = myapply
// bind
function mybind(that) {
let fn = this;
return function(...args){
fn.apply(that, args);
}
}
Function.prototype.mybind = mybind
// new
function myNew(fn, ...args){
let obj = Object.create(fn.prototype);
fn.apply(obj, args);
return obj;
}
// instanceof实现
function instanceOf(origin, target) {
while(1){
if(origin.__proto__ == target.prototype){
return true
}
if(origin.__proto__ == null){
return false
}
origin = origin.__proto__
}
}
// 数组乱序
function shuffle(arr) {
let len = arr.length;
for (let i = 0; i < len - 1; i++) {
let index = parseInt(Math.random() * (len - i));
let temp = arr[index];
arr[index] = arr[len - i - 1];
arr[len - i - 1] = temp;
}
return arr;
}
Javascript手写函数
最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
- 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
- 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
- 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
推荐阅读更多精彩内容
- 1 call和apply是怎样使用的?call函数接收多个参数,第一个参数是this的指向,之后的参数都是函数的参...
- 1.数组扁平化初探 ES6中数组的扩展引入了flat和flatMap:数组的flat方法: 数组的flatMap方...
- 写一个js函数,实现对一个数字每3位加一个逗号,如输入100000, 输出100,000 最简单的方法就是调用to...
- 先认识JS的ArrayforEach、map和reduce方法: 因为typescript中有类型标注,我们看一下...