# 手写代码无敌秘籍(二)
# 数据类型判断 typeof
function _typeof(obj) {
let res = Object.prototype.toString.call(obj).split(" ")[1];
res = res.substring(0, res.length - 1).toLowerCase();
return res;
}
_typeof(null); // 'null'
_typeof(undefined); // 'undefined'
_typeof("s"); // 'string'
_typeof(1); // 'number'
_typeof([]); // 'array'
_typeof({}); // 'object'
_typeof(new Date()); // 'date'
_typeof(new Set()); // 'set'
_typeof(new Map()); // 'map'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
# 继承
function Father() {
this.name = "father";
this.age = 40;
}
Father.prototype.say = function () {
console.log(111);
};
function Son() {
Father.call(this);
this.age = 18;
}
Son.prototype = Object.create(Father.prototype, {
constructor: {
value: Son,
},
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 数组去重
ES6
const unique = (arr) => [...new Set(arr)];
1
ES5
// 方法一
function unique1(arr) {
var res = arr.filter(function (item, index, array) {
return array.indexOf(item) === index;
});
return res;
}
// 方法二
function unique2(arr) {
let map = {};
let _res = [];
for (let i = arr.length - 1; i > 0; i--) {
if (!map[arr[i]]) {
_res.push(arr[i]);
map[arr[i]] = true;
}
}
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
# 数组扁平化
// 方法一
function flatten1(arr) {
while (arr.some((item) => Array.isArray(item))) {
arr = [].concat(...arr);
}
return arr;
}
// 方法二 普通递归
function flatten2(arr) {
var result = [];
for (var i = 0, len = arr.length; i < len; i++) {
if (Array.isArray(arr[i])) {
result = result.concat(flatten(arr[i]));
} else {
result.push(arr[i]);
}
}
return result;
}
// 方法三 reduce 递归
function flatten3(array) {
return array.reduce(
(arr, cur) =>
Array.isArray(cur) ? [...arr, ...flatten3(cur)] : [...arr, cur],
[]
);
}
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
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
# 深拷贝
const isComplexDataType = (obj) =>
(typeof obj === "object" || typeof obj === "function") && obj !== null;
const deepClone = function (obj, hash = new WeakMap()) {
// 如果成环了,参数obj = obj.loop = 最初的obj
// 会在WeakMap中找到第一次放入的obj提前返回第一次放入WeakMap的cloneObj
if (hash.has(obj)) return hash.get(obj);
let type = [Date, RegExp, Set, Map, WeakMap, WeakSet];
if (type.includes(obj.constructor)) return new obj.constructor(obj);
let allDesc = Object.getOwnPropertyDescriptors(obj); //遍历传入参数所有键的特性
let cloneObj = Object.create(Object.getPrototypeOf(obj), allDesc); //继承原型
hash.set(obj, cloneObj);
for (let key of Reflect.ownKeys(obj)) {
//Reflect.ownKeys(obj)可以拷贝不可枚举属性和符号类型
// 如果值是引用类型(非函数)则递归调用deepClone
cloneObj[key] = isComplexDataType(obj[key])
? deepClone(obj[key], hash)
: obj[key];
}
return cloneObj;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 发布订阅
# 解析 URL 参数为对象
# 字符串模板
# 图片懒加载
# 函数防抖
# 函数节流
# 函数柯里化
# 偏函数
# JSONP
# AJAX
# forEach
# map
# filter
# some
# reduce
# call
# apply
# bind
# 实现 new 关键字
# 实现 instanceof 关键字
# 实现 Object.create
# 实现 Object.assign
# 实现 JSON.stringify
# 实现 JSON.parse
# 实现 Promise
# Promise.resolve
# Promise.reject
# Promise.all
# Promise.race
# Promise.allSettled
# Promise.any
#
← 手写代码无敌秘籍(一) 大佬的面经 →