手写集合

bind

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Function.prototype.myBind = function (context) {
//返回一个绑定this的函数,我们需要在此保存this
let self = this;
// 可以支持柯里化传参,保存参数
let arg = [...arguments].slice(1);
// 返回一个函数
return function () {
//同样因为支持柯里化形式传参我们需要再次获取存储参数
let newArg = [...arguments];
console.log(newArg);
// 返回函数绑定this,传入两次保存的参数
//考虑返回函数有返回值做了return
return self.apply(context, arg.concat(newArg));
};
};

call

1
2
3
4
5
6
7
8
9
10
11
12
Function.prototype.myCall = function (context) {
if (typeof context === undefined || typeof context === null) {
context = window
}
context = context || window;
const symbol = Symbol();
context[symbol] = this;
const args = [...arguments].slice(1);
const result = context[symbol](...args);
delete context[symbol];
return result;
};

apply

1
2
3
4
5
6
7
8
9
10
11
Function.prototype.myApply = function (context) {
context = context || window;
const symbol = Symbol();
context[symbol] = this;
const args = [...arguments].slice(1, 2);
console.log(context[symbol]);
console.log(args);
const result = context[symbol](...args[0]);
delete context[symbol];
return result;
};

deepClone

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function deepClone (org, tar){
if (typeof org !== 'object') {
return org;
}
var tar = tar || {},
toStr = Object.prototype.toString,
arrType = '[object Array]';

for (var key in org) {
if (org.hasOwnProperty(key)) {
if (typeof org[key] === 'object' && org[key] !== null) {
tar[key] = toStr.call(org[key]) === arrType ? [] : {};
deepClone(org[key], tar[key]);
}else {
tar[key] = org[key];
}
}
}

return tar;
}

filter

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Array.prototype.myFilter = function(fn) {
var arr = this,
len = arr.length,
arg2 = arguments[1] || window,
newArr = [],
item;

for (var i = 0; i < len; i++) {
item = structuredClone(arr[i]);
var flag = fn.apply(arg2, [item, i, arr]);

if (flag) {
newArr.push(item)
}
}
return newArr
};

map

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Array.prototype.myMap = function (fn) {
var arr = this,
len = arr.length,
arg2 = arguments[1] || window,
newArr = [],
item;

for(var i = 0; i < len; i++) {
item = structuredClone(arr[i]);
var newItem = fn.apply(arg2, [item, i, arr]);
newArr.push(newItem);
}

return newArr;
}

new

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/* 
new 的过程都发生了什么
1、新生成了一个对象
2、链接到原型
3、绑定 this
4、返回新对象
*/
function create() {
let Con = [].shift.call(arguments);
let obj = Object.create(Con.prototype);
let result = Con.apply(obj, arguments);
// 如果执行结果有返回值并且是一个对象, 返回执行的结果, 否则, 返回新创建的对象
return result instanceof Object ? result : obj;
}

proxy

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
34
35
36
function MyProxy (target, handler) {

let _target = deepClone(target);

Object.keys(_target).forEach((key) => {
Object.defineProperty(_target, key, {
get () {
return handler.get && handler.get(target, key);
},
set (newVal) {
handler.set && handler.set(target, key, newVal);
}
})
})

return _target;

function deepClone (org, tar){
var tar = tar || {},
toStr = Object.prototype.toString,
arrType = '[object, Array]';

for (var key in org) {
if (org.hasOwnProperty(key)) {
if (typeof org[key] === 'object' && org[key] !== null) {
tar[key] = toStr.call(org[key]) === arrType ? [] : {};
deepClone(org[key], tar[key]);
}else {
tar[key] = org[key];
}
}
}

return tar;
}
}

reduce

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/* 
reduce 是没有第三个参数修改 this 指向的
重写方法 myReduce 加入了
*/
Array.prototype.myReduce = function (fn, intialValue) {
var arr = this,
len = this.length,
arg2 = arguments[2] || window,
item;

for (var i = 0; i < len; i++) {
item = structuredClone(arr[i]);
intialValue = fn.apply(arg2, [intialValue, item, i, arr]);
}

return intialValue;
}

every

1
2
3
4
5
6
7
8
9
10
11
12
13
Array.prototype.myEvery = function (fn) {
var arr = this,
len = arr.length,
arg2 = arguments[1] || window;

for(var i = 0; i < len; i++) {
var flag = fn.apply(arg2, [arr[i], i, arr]);
if(!flag) {
return false;
}
}
return true;
}

some

1
2
3
4
5
6
7
8
9
10
11
12
13
Array.prototype.mySome = function (fn) {
var arr = this,
len = arr.length,
arg2 = arguments[1] || window;

for(var i = 0; i < len; i++) {
var flag = fn.apply(arg2, [arr[i], i, arr]);
if(flag) {
return true;
}
}
return false;
}

forEach

1
2
3
4
5
6
7
8
9
10
11
12
Array.prototype.myForEach = function (fn) {
var arr = this,
len = arr.length,
// 如果没传第二个参数,this还是指向window
arg2 = arguments[1] || window;
// console.log(arr);

for(var i = 0; i < len; i++) {
// 如果传第二个参数,需要更改this指向
fn.apply(arg2, [arr[i], i, arr]);
}
}

debounce(防抖)

1
2
3
4
5
6
7
8
9
10
function debounce(fn, delay) {
let timer = null;
return function (...args) {
let context = this;
if(timer) clearTimeout(timer);
timer = setTimeout(function() {
fn.apply(context, args);
}, delay);
}
}

throttle(节流)

1
2
3
4
5
6
7
8
9
10
function throttle(fn, delay) {
let lastCall = 0;
return function(...args) {
const now = new Date().getTime();
if (now - lastCall >= delay) {
fn(...args);
lastCall = now;
}
};
}

排序算法

快速排序

时间复杂度 O(nlogn)

1
2
3
4
5
6
7
function quickSort(array) {
if (array.length < 2) return array
let pivot = array[array.length - 1]
let left = array.filter((v, i) => v <= pivot && i != array.length -1)
let right = array.filter(v => v > pivot)
return [...quickSort(left), pivot, ...quickSort(right)]
}

冒泡排序

时间复杂度 O(n^2)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
const bubbleSort = (arr) => {
const length = arr.length;
if (length <= 1) return;
// i < length - 1 是因为外层只需要 length-1 次就排好了,第 length 次比较是多余的。
for (let i = 0; i < length - 1; i++) {
let hasChange = false; // 提前退出冒泡循环的标志位
// j < length - i - 1 是因为内层的 length-i-1 到 length-1 的位置已经排好了,不需要再比较一次。
for (let j = 0; j < length - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
[arr[j], arr[j + 1]] = [arr[j + 1], arr[j]]
hasChange = true; // 表示有数据交换
}
}
if (!hasChange) break; // 如果 false 说明所有元素已经到位,没有数据交换,提前退出
}
console.log(arr);
};

睡眠函数

1
2
3
4
5
function sleep(time){
return new Promise(function(resolve){
setTimeout(resolve, time);
});
}

手写集合
https://l1ushun.github.io/2022/12/03/write/
作者
liu shun
发布于
2022年12月3日