1.手写instanceof
实例对象 instanceof 构造函数
function myinstanceof(left, right){
let prototype= right.prototype;
let proto = left.__proto__;
while(true) {
if(proto===prototype) return true;
if(proto===null) return false;
proto=proto.__proto__;
}
}
2.手写new
new(obj)得到一个obj的实例对象
function mynew(obj){
let newobj={};
newobj.__proto__=obj.prototype;
obj.apply(newobj);
return newobj;
}
3.手写apply
fn.apply(obj,[]) => obj.fn() => del fn
function myapply(obj,args){
obj = (obj===null||obj===undefined) ? window : Object(obj);
const fn = Symbol();
obj.fn=this;
const result = obj.fn(...args);
delete obj[fn];
return result
}
4.手写call
function mycall(obj,...args){
obj = (obj===null||obj===undefined) ? window : Object(obj);
const fn = Symbol();
obj.fn=this;
const result = obj.fn(...args);
delete obj[fn];
return result
}
5.手写bind
利用mycall
function mybind(obj,...args){
const that =this;
return function(...args){
return that.mycall(obj,...args);
}
}
function mybind2(obj,...args){
const that=this;
return function(...args2){
obj=(obj===null||obj===undefined)?window:Object(obj);
const fn = Symbol();
obj.fn=that;
const result = obj.fn(...args,...args2);
delete obj[fn];
return result;
}
}
6.手写getType
const getType = function(obj) {
return Object.prototype.toString.call(obj).slice(8,-1);
}
console.log(getType({}));//Object
console.log(getType(null));//Null
console.log(getType(undefined));//Undefined
console.log(getType([]));//Array
console.log(getType(12));//Number
console.log(getType('string'));//String
console.log(getType(()=>{}));//Function
7.手写deepCopy
function deepcopy(obj) {
if(typeof obj ==='object' && obj!==null) {
let container;
if(Array.isArray(obj)===true ) {
container=[];
for(let i of obj) {
if(typeof i ==='object') {
container.push(deepcopy(i));
}
else container.push(i);
}
}
else {
container={};
for(let i in obj) {
if(typeof obj[i] ==='object') {
container[i]=deepcopy(obj[i]);
}
else container[i]=obj[i];
}
}
return container;
}
else return obj;
}
8.手写Promise.race
第一个返回的结果 不管resolve还是reject
Promise.myrace=function(arr){
return new Promise((resolve,reject)=>{
arr.forEach(item=>{Promise.resolve(item).then(res=>{
resolve(res);
},err=>{
reject(err)
})})
})
}
//arr.forEach(item=>后面有没有大括号都可
//Promise.myrace([1,2]).then(res=>{
//console.log(res);
})
9.手写Promise.all
全resolve才返回resolve,返回一个数组存全部Promise的结果,有一个reject即返回reject
Promise.myall= function(arr){
let result=[];
let count=0;
return new Promise((resolve,reject)=>{
arr.forEach((item,index)=>{Promise.resolve(item).then(res=>{
result[index]=res;
count++;
if(count===arr.length) resolve(result);
},err=>{
reject(err);
})})
})
}
//Promise.myall([1,2]).then(res=>{
// console.log(res);
})
10.手写Promise.allSettled
所有结果无论成功与否都会收集起来
返回的是一个数组,status标记状态,成功和失败分别将结果放在value和reason中
Promise.myAllSettled =function(arr){
let result=[];
let count=0;
return new Promise((resolve,reject)=>{
arr.forEach((item,index)=>{Promise.resolve(item).then(res=>{
result[index]={status:'fullfilled',value:res};
count++;
if(count===arr.length) resolve(result);
},err=>{
result[index]={status:'rejected',reason:err};
count++;
if(count===arr.length) resolve(result);
})})
})
}
11.手写Promise.any
正好和promise.all相反
有一个成功即为成功 全部失败则为失败
Promise.myAny =function(arr){
let result=[];
let count=0;
return new Promise((reslove,reject)=>{
arr.forEach((item,index)=>{Promise.resolve(item).then(res=>{
resolve(res);
},err=>{
result[index]=err;
count++;
if(count===arr.length) reject(result);
})})
})
}
12.数组扁平化
function myflat(arr){
for(let i=0;i<arr.length;i++){
if(Array.isArray(arr[i])) {
arr.splice(i,1,...arr[i]);
myflat(arr)
}
}
return arr
}
13.全排列
给定一个不含重复数字的数组,返回其所有可能的全排列,可以任意顺序返回
function allsort(nums){
let res=[];
let temp=[];
let used=new Array(nums.length).fill(false);
function dfs(){
if(temp.length===nums.length){
res.push(temp.slice());
return;//return有没有都可
}
for(let i=0;i<nums.length;i++) {
if(used[i]===true) continue;
temp.push(nums[i]);
used[i]=true;
dfs();
temp.pop();
used[i]=false;
}
}
dfs()
return res;
}
14.防抖
function debounce(fn,delay){
let s=null
return function(...args){
clearTimeout(s)
s= setTimeout(()=>{
//fn(...args) 这里不写fn()的原因是:fn()指向undefined 需要将fn的this重新指向
fn.apply(this,args)
},delay)
}
}
15.节流
function throttle(fn,delay){
let flag=false;
return function(...args){
if(!flag){
flag=true
setTimeout(()=>{
//fn(...args) 这里不写fn()的原因是:fn()指向undefined 需要将fn的this重新指向
fn.apply(this,args)
flag=false
},delay)
}
}
}
16.手写reduce
Array.prototype.reducer=(fun,init,thisarg=window)=>{
let accumulator=(init==='undefined')?this[0]:init;
let start=(init==='undefined')?1:0;
let len=this.length;
for(let i=start;i<len;i++){
accumulator=fun.apply(thisarg,[accumulator,this[i],i,this]);
}
return accumulator;
}