js 手写函数

unshift()

1
2
3
4
5
6
7
8
9
10
11
const arr = [1, 2.3];
arr.myUnshift(4, 5, 6);
Array.prototype.myUnshift = function () {
const len = arguments.length;
for (let i = len - 1; i >= 0; i--) {
this.slice(0, 0, arguments[i]);
}
return this.length;
};

console.log(arr.myUnshift(4, 5, 6), arr);

去重

1
2
3
4
5
6
7
//(method) Array<any>.indexOf(searchElement: any, fromIndex?: number | undefined): number

Array.prototype.myUnique = function () {
return this.filter((v, idx) => {
return this.indexOf(v, 0) === idx;
});
};

1
2
3
Array.prototype.myUnique = function () {
return [...new Set(this)];
};

获取指定范围内的随机数

1
2
3
4
5
6
7
8
9
10
function fn(min, max) {
//(min,max)
// return Math.round(Math.random() * (max - min - 2) + (min + 1));
//[min,max]
// return Math.round(Math.random() * (max - min ) + min);
//(min,max)
// return Math.ceil(Math.random() * (max - min) + (min));
//(min,max)
return Math.floor(Math.random() * (max - min) + min);
}

打印 100 之内的质数

1
2
3
4
5
6
7
8
9
10
11
12
13
let count;
for (let i = 2; i < 100; i++) {
for (let j = 1; j <= i; j++) {
if (i % j === 0) {
count++;
}
}
//质数只能被1和它本身整除
if (count === 2) {
console.log(i);
}
count = 0;
}

如何提取 URL 中的参数

1
2
3
4
5
6
7
8
const url = "https://baidu.com?a=1&b=2&c=3#hash";
function queryURLParams(URL) {
let url = URL.split("?")[1];
const urlSearchParams = new URLSearchParams(url);
const params = Object.fromEntries(urlSearchParams.entries());
return params;
}
console.log(queryURLParams(url));

数组随机排序

1
2
3
4
5
6
7
8
9
10
function result(arr) {
for (let i = 0; i < arr.length; i++) {
let randomIndex = parseInt(Math.random() * arr.length);

let curNum = arr[i];
arr[i] = arr[randomIndex];
arr[randomIndex] = curNum;
}
return arr;
}

1
2
3
const arr = [1, 2, 3, 4, 5, 6, 7, 8];
arr.sort(() => Math.random() - 0.5);
console.log(arr);

实现迭代的方式实现 flatten

1
2
3
4
5
6
7
8
let arr = [1, 2, [3, 4, 5], 6, [7, [8, 9, [10, [11, 12]]]]];

const flatten = function (arr) {
while (arr.some((v) => Array.isArray(v))) {
arr = [].concat(...arr);
}
return arr;
};

1
2
3
const flatten = function (arr) {
return [].concat(...arr.map((v) => (Array.isArray(v) ? flatten(v) : v)));
};

两数之和

// nums target

1
2
3
4
5
6
7
8
9
10
const nums = [2, 7, 11, 17];
const target = 9;
function twoSum(nums, target) {
for (let i = 0; i < nums.length; i++) {
const targetIndex = nums.indexOf(target - nums[i]);
if (targetIndex > -1 && targetIndex !== i) {
return [i, targetIndex];
}
}
}

给 a,b,c 三个请求,c 在 a,b 获取完数据之后再发送请求

// 1. promise.all

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const fs = require("fs");
let arr = [];
function fn(data) {
arr.push(data);
if (arr.length === 2) {
console.log(arr);
}
}

fs.readFile("./a.text", "utf-8", (err, data) => {
fn(data);
});

fs.readFile("./b.text", "utf-8", (err, data) => {
fn(data);
});

如何实现一个事件发布订阅

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
37
38
39
40
41
42
43
44
45
46
47
48
class EventEmitter {
handlers = {};
on(type, handler, once = false) {
if (!this.handlers[type]) {
this.handlers[type] = [];
}
if (!this.handlers[type].includes(handler)) {
this.handlers[type].push(handler);
handler.once = once;
}
}
once(type, handler) {
this.on(type, handler, true);
}
off(type, handler) {
if (this.handlers[type]) {
this.handlers[type] = this.handlers[type].filter((h) => h !== handler);
}
}
trigger(type) {
if (this.handlers[type]) {
this.handlers[type].forEach((handler) => {
handler.call(this);
if (handler.once) {
this.off(type, handler);
}
});
}
}
}

const ev = new EventEmitter();
function handler1() {
console.log("handler1");
}
function handler2() {
console.log("handler2");
}
function handler3() {
console.log("handler3");
}

ev.on("test", handler1);
ev.once("test", handler2);
ev.on("test", handler3);

ev.trigger("test");
ev.trigger("test");

apply、call、bind

apply

1
2
3
4
5
6
7
Function.prototype.myApply = function (context, args) {
context = context || window;
context.fn = this;
let result = context.fn(...args);
delete context.fn;
return result;
};

call

1
2
3
4
5
6
7
Function.prototype.myCall = function (context, ...args) {
context = context || window;
context.fn = this;
let result = context.fn(...args);
delete context.fn;
return result;
};

bind

1
2
3
4
5
6
Function.prototype.myBind = function (context, ...arg1) {
let that = this;
return function (...arg2) {
return that.apply(context, [...arg1, ...arg2]);
};
};

Promise.all

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
Promise.all = function (promises) {
return new Promise((resolve, reject) => {
if (typeof promises[Symbol.iterator] !== "function") {
reject("Type error");
}

if (promises.length === 0) {
resolve([]);
} else {
const res = [];
let count = 0;
const len = promises.length;
for (let i = 0; i < len; i++) {
Promise.resolve(promises[i])
.then((data) => {
res[i] = data;
if (++count === len) {
resolve[res];
}
})
.catch((err) => {
reject(err);
});
}
}
});
};

instanceof

1
2
3
4
5
6
7
8
9
10
11
12
13
function myInstanceof(target, origin) {
if (typeof target !== "object" || target === null) return false;

if (typeof origin !== "function")
throw new TypeError("origin must be function");

let proto = Object.getPrototypeOf(target);
while (proto) {
if (proto === origin.prototype) return true;
proto = Object.getPrototypeOf(proto);
}
return false;
}

reduce

1
2
3
4
5
6
7
8
9
Array.prototype.reduce = function (cb, initialValue) {
let arr = this,
total = arr[0] || initialValue;

for (let i = initialValue ? 0 : 1; i < arr.length; i++) {
cb(total, arr[i], i, arr);
}
return total;
};