数组去重
let arr = [1,21,3,4,5,1,3,1];
利用Set数据结构
function unique(arr){
// 利用es6的set数据结构
return [...new Set(arr)];
}
利用Array.prototype.filter函数
function unique(arr){
return arr.filter((item,index) => {
// 判断是否有出现索引号不一致情况,若有则说明有重复
return arr.indexOf(item) === index;
});
}
利用Array.prototype.includes函数
function unique(arr){
const newArr = [];
arr.forEach(item => {
// 判断新数组里是否有该item
if(newArr.includes(item)) return;
newArr.push(item);
})
return newArr;
}
利用Array.prototype.indexOf函数
function unique(arr){
const newArr = [];
arr.forEach(item => {
// 若item从未出现在新数组里,将item加入新数组
if(newArr.indexOf(item) === -1) newArr.push(item)
// if(!newArr.includes(item)) newArr.push(item)
})
return newArr;
}
数组扁平化
let arr = [[1], [2, 3], [4, 5, 6, [7, 8, [9, 10, [11]]]], 12];
// 原生
arr.flat(Infinity);
利用字符串转换
function flat(arr){
let arrStr = arr.toString();
let newArr = arrStr.split(',');
return newArr.map(item => Number(item));
}
完美版本,不改变变量类型
function flat(arr,maxDepth = 1){
let counter = 0;
// 利用迭代
while(arr.some(item => Array.isArray(item))){
if(counter < maxDepth){
++counter;
arr = [].concat(...arr);
}
}
return arr;
}
柯里化
function curring(fn,...argsOne){
// 若参数不够则继续返回函数,继续接收参数
if(argsOne.length<fn.length){
return (...argsTwo)=>{
return curring(fn,...argsOne.concat(argsTwo));
}
}else{
// 若参数足够则直接返回函数调用结果
return fn.call(this,...argsOne);
}
}
function add(a,b,c,d,e){
return a + b + c + d + e;
}
let fn = curring(add);
console.log(fn(1,2,3,4,5))
console.log(fn(1,2,3,4)(5))
console.log(fn(1,2)(3,4,5))
console.log(fn(1)(2)(3)(4)(5))
new
new操作符做的事情
- 判断操作对象是否为函数,若是则创建一个空对象。若不是则抛出类型错误
- 将该空对象的原型指向构造函数的原型
- 执行构造函数,将this指向该空对象
- 判断构造函数执行结果,若为对象则返回对象,若不是则返回开始时创建的对象
function myNew(Constructor,...args){
if(Constructor instanceof Function){
const obj = Object.create(Constructor.prototype);
const res = Constructor.call(obj,...args);
return res instanceof Object ? res : obj;
}else{
// 值不是函数类型,抛出错误
throw new Error(`TypeError:${Constructor} is not a Constructor`);
}
}
instanceof
instanceof
就是根据构造函数的原型链网上查找,找到即返回true
,找不到则返回false
- 判断右操作数是否为函数类型,是则继续。否则返回类型错误
- 左操作数的原型不是则继续获取该原型的原型
- 若最终找到
Object.prototype
的__proto
则返回false,查找失败。否则返回true
function myInstanceof(left,right){
if(typeof right === 'function'){
let Lproto = Object.getPrototypeOf(left);
while(true){
// 找到终点null时,直接返回false
if(!Lproto) return false;
if(Lproto === right.prototype) return true;
Lproto = Object.getPrototypeOf(Lproto);
}
}else{
throw new Error(`Right-hand side of 'instanceof' is not callable`)
}
}