# 手写代码
# debounce 防抖
function debounce(fn, delay = 500) {
let timer = null;
return function() {
if (timer) {
clearTimeout(timer);
timer = null;
}
timer = setTimeout(() => {
fn.apply(this, arguments);
timer = null;
}, delay);
};
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# throttle 节流
function throttle(fn, delay = 500) {
let timer = null;
return function() {
if (timer) {
return;
}
timer = setTimeout(() => {
fn.apply(this, arguments);
timer = null;
}, delay);
};
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# cloneDeep 深拷贝
function cloneDeep(arg) {
//不是数组,或者是 null || undefined
if (typeof arg !== "object" || arg == null) {
return arg;
}
let res;
if (arg instanceof Array) {
res = [];
} else {
res = {};
}
for (let key in arg) {
if (arg.hasOwnProperty(key)) {
res[key] = cloneDeep(arg[key]);
}
}
return res;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# isEqual 深度比较
function isObject(obj) {
return typeof obj === "object" && obj !== null;
}
function isEqual(obj1, obj2) {
if (!isObject(obj1) || !isObject(obj2)) {
return obj1 === obj2;
}
if (obj1 === obj2) {
return true;
}
const obj1Keys = Object.keys(obj1);
const obj2Keys = Object.keys(obj2);
if (obj1Keys.length !== obj2Keys.length) {
return false;
}
for (let key in obj1) {
let res = isEqual(obj1[key], obj2[key]);
if (!res) {
return false;
}
}
return true;
}
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
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
# new
function myNew(fn, ...arg) {
let obj = Object.create(fn.prototype);
let res = fn.apply(obj, arg);
return res instanceof Object ? res : obj;
}
1
2
3
4
5
2
3
4
5
# call
Function.prototype.call = function(_this, ...arg) {
let __this = _this ? _this : Object(_this);
const fnKey = new Symbol("fnKey");
__this[fnKey] = this;
const res = __this[fnKey](...arg);
delete __this[fnKey];
return res;
};
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# bind
Function prototype.bind = function (_this,...arg){
let fn = this;
return function (...arg2){
return fn.apply(_this,[...arg,...arg2])
}
}
1
2
3
4
5
6
2
3
4
5
6
# curry(函数柯里化)
function curry(fn, ...arg) {
let length = fn.length;
return function(...arg2) {
let newArg = [...arg, ...arg2];
if (newArg.length < length) {
return curry.call(this, fn, ...newArg);
} else {
return fn.call(this, ...newArg);
}
};
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# instanceof
- instanceof 是用来判断 A 是否为 B 的实例,表达式为:A instanceof B,如果 A 是 B 的实例,则返回 true,否则返回 false。
- instanceof 运算符用来测试一个对象在其原型链中是否存在一个构造函数的 prototype 属性。
- 不能检测基本数据类型,在原型链上的结果未必准确,不能检测 null,undefined
- 实现:遍历左边变量的原型链,直到找到右边变量的 prototype,如果没有找到,返回 false
function myInstanceOf(a, b) {
let left = a.__proto__;
let right = b.prototype;
while (true) {
if (left == null) {
return false;
}
if (left == right) {
return true;
}
left = left.__proto__;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13