1.instanceof的实现
原理:按原型链进行查找。
//1.instance
function myInstanceOf(left,right){
while(true){
if(left.__proto__ === null){
return false
};
if(left.__proto__ === right.prototype){
return true;
}
left = left.__proto__
}
}
function Parent(){};
function Son(){}
Son.prototype = new Parent()
var baby = new Son()
var arr = []
console.log(myInstanceOf(arr,Array))//true
console.log(myInstanceOf(baby,Parent))//true
2.new的实现
1.原型链;2.调用构造函数;3.返回值判断
/**
* new的实现
*/
function myNew(father,...args){
//1.指定原型链
var obj = Object.create(father.prototype);
//2.调用构造函数
var res = father.call(obj,...args);
//3.返回值判断
return typeof res === "object" ? res : obj
};
function Person(name){
this.name = name
}
var xixi = myNew(Person,"xixixi");
console.log(xixi.name)//xixixi
3.缓存函数的实现
1.闭包;2.返回一个函数去接受参数
/**
* 缓存函数的实现
*/
function memorize(fn){
var cache = {};
return function(){
let key = JSON.stringify(arguments);
if(cache[key]){
return cache[key];
}else{
var res = fn.call(null,...arguments);
cache[key] = res;
return res;
}
}
}
function add(a,b){
console.log("开始缓存")
return a+b
}
var add1 = memorize(add)
console.log(add1(1,2))
console.log(add1(1,2))
console.log(add1(2,2))
console.log(add1(2,2))
// 开始缓存
// 3
// 3
// 开始缓存
// 4
// 4
4.函数柯理化实现
1.返回一个函数去接受参数;2.判断参数的数目
/**
* 4.柯理化实现
*/
function curry(fn,args){
var len = fn.length;
var args = args || [];
return function(){
var newArgs = args.concat([...arguments]);
//参数超过len没判断,可以加一个
if(newArgs.length < len){
// console.log(this)
return curry.call(this,fn,newArgs);
}else{
return fn(...newArgs);
}
}
};
function add(a, b,c,d) {
return a + b+c+d;
}
var CAdd = curry(add);
var c = CAdd(1)(2)
console.log(c(3)(4));//10
5.call的实现
/**
* call实现
*/
Function.prototype.myCall = function (context, ...args) {
if (!context || context === null) {
context = window;
}
// 创造唯一的key值 作为我们构造的context内部方法名
let fn = Symbol();
context.fn = this; //this指向调用call的函数,相当于将调用call函数的函数,赋值给context.fn,以便context的环境中稍后执行
// 执行函数并返回结果 相当于把自身作为传入的context的方法进行调用了
var res = context.fn(...args);//这里用到了Es6的语法"...",call是ES3的东西
delete context.fn//删除掉这个没用属性
return res
};
var obj = {
name:"zhu"
}
function foo(){
var name = "zhao";
console.log(this.name)
}
foo.myCall(obj)
6.apply的实现
Function.prototype.myApply = function(context,arr){
if(!Array.isArray(arr)){
throw new Error("传入的第二个参数必须为数组")
};
if(!context || context === null){
context = window
};
var fn = Symbol();
context.fn = this;
var res = context.fn(...arr);
delete context[fn]
return res
}
var fo = {
value: 1
};
var value = 3
function bar(name, age) {
console.log(name)
console.log(age)
console.log(this.value);
}
bar.myApply(fo,['kevin', 18])
//kevin
//18
//1
/**
* 7.bind实现
* 1.改变this 2.返回一个绑定this的函数 3.接收参数 4.柯理化传参数
*/
Function.prototype.myBind = function (context){
var args = [...arguments].slice(1);
var _this = this;
return function(){
var newArgs = [...arguments];
return _this.apply(context,args.concat(...newArgs))
}
};
let Person = {
name: 'zhu',
say(age) {
console.log(this)
console.log(`我叫${this.name}我今年${age}`)
}
}
Person1 = {
name: 'zhao'
}
var fn = Person.say.myBind(Person1);
fn(11)
// { name: 'zhao' }
// 我叫zhao我今年11
8.深拷贝
function deepCopy(obj){
if(typeof obj != "object") {
throw new Error("输入必须为对象或者数组")
};
var newObj = Array.isArray(arr) ? [] : {};
for(var index in obj) {
if(obj.hasOwnProperty(index)){
//hasOwnProperty忽略掉那些从原型链上继承到的属性
if (typeof obj[index] === "object") {
newObj[index] = deepCopy(obj[index]);
} else {
newObj[index] = obj[index]
}
}
}
return newObj;
}
var arr = [1,2,3,[4,5]]
Array.prototype[4] = 6
console.log(arr[4])//6
var newArr = deepCopy(arr)
console.log(newArr);//[ 1, 2, 3, [ 4, 5 ] ]
arr[3] = 4;
console.log(newArr);//[ 1, 2, 3, [ 4, 5 ] ]
9.防抖
每次触发事件清空上次事件的定时器
/**
* 9.防抖
*/
function debounce(fn,delay){
var timer = null;
return function(){
if(timer){
clearTimeout(timer);
}
timer = setTimeout(fn,delay)
}
}
10.节流
回调触发后将lastTime进行更新
function throttle(fn,delay){
var lastTime = 0
return function(){
var nowTime = Date.now()
if(nowTime - lastTime > delay){
fn.call(this)
lastTime = nowTime
}
}
}
11.某种迭代器
function makeIterator(arr){
var index = 0
return {
next: function (){
return index >= arr.length ? {
value:undefined,
done:true
}:{
value:arr[index++],
done:false
}
}
}
};
let arr = [1,2,3,4]
const itArr = makeIterator(arr)
console.log(itArr.next())//{ value: 1, done: false }
console.log(itArr.next())//{ value: 2, done: false }
console.log(itArr.next())//{ value: 3, done: false }
console.log(itArr.next())//{ value: 4, done: false }
console.log(itArr.next())//{ value: undefined, done: true }
12.实现Object.create()
1.Object.create(p)方法创建一个新对象,使用现有的对象p来提供新创建的对象的__proto__。 2.在object()函数内部, 先创建一个临时性的构造函数, 然后将传入的对象作为这个构造函数的原型,最后返回了这个临时类型的一个新实例.
Object.prototype.myCreate = function(p){
function F(){};
F.prototype = p;
return new F();
}
var Person = {
name:"xixixi",
age:18
}
var p = Object.myCreate(Person);
console.log(p.name)//xixixi
console.log(Person.isPrototypeOf(p))//true
13.setInterval的实现
使用setTimeout来实现
/**
* 13.setInterval的实现
* @param fn
* @param delay
* @param count
*/
function myInterval(fn,delay,count){
function In(){
if(count--){
fn();
setTimeout(In,delay)
}
}
setTimeout(In,delay)
}
let a = () => {
console.log(1)
}
myInterval(a,1000,5)
14.Promise.all的实现
/**
* 14.Promise.all()的实现
* @param p
* @returns {Promise<unknown>}
*/
function myPromiseAll(p){
if(Array.isArray(p) === false){
throw new Error("传入的参数必须为一个数组");
};
return new Promise((resolve,reject) => {
var result = [];
var count = 0;
p.forEach((promise,index) => {
Promise.resolve(promise).then((res) => {
result[index] = res;
count++;
count === p.length && resolve(result)
},(err) => {
reject(err)
})
})
})
}
let p1 = new Promise(((resolve, reject) => {
setTimeout(() => {
resolve(1)
},200)
})),
p2 = Promise.resolve(2),
p3 = 3
myPromiseAll([p1, p2, p3]).then((res)=>{
console.log(res, 'res') //[1,2,3] res
}, (err)=>{
console.log(err, 'err')
})
15.Promise.all的变体,无论成功或者失败都输出。
/**
*
* @param p
* @returns {Promise<unknown>}
*/
Promise.myPromise_all_settled = function(p){
if(Array.isArray(p) === false){
throw new Error("传入的参数应该为数组");
}
return new Promise((resolve,reject) => {
var result = [];
var count = 0;
p.forEach((promise,index) => {
Promise.resolve(promise).then((res) => {
count++
result[index] = {
status: "fulfilled",
value: res
}
if(count === p.length){
resolve(result)
}
},(err) => {
count++;
result[index] = {
status: "rejected",
value: err
};
if(count === p.length){
resolve(result)
};
})
})
})
};
const p1 = Promise.resolve(1)
const p2 = new Promise((resolve) => {
setTimeout(() => resolve(2), 1000)
})
const p3 = new Promise((resolve) => {
setTimeout(() => resolve(3), 3000)
})
const p4 = Promise.reject('err4')
const p5 = Promise.reject('err5')
// 1. 所有的Promise都成功了
const p11 = Promise.myPromise_all_settled([ p1, p2, p3 ,p4,p5])
.then((res) => {console.log(res)});
// 输出:[
// { status: 'fulfilled', value: 1 },
// { status: 'fulfilled', value: 2 },
// { status: 'fulfilled', value: 3 },
// { status: 'rejected', value: 'err4' },
// { status: 'rejected', value: 'err5' }
// ]
16.eventBus实现,事件总线,发布订阅模式
/**
* eventBus实现,事件总线,发布订阅模式
*/
class EventBus {
constructor() {
this.events = this.events || {};
};
$on(eventName, callback) {
if (this.events[eventName]) {
this.events[eventName].push(callback);
} else {
this.events[eventName] = [callback]
}
};
$emit(eventName, data) {
if (this.events[eventName]) {
this.events[eventName].forEach((callback) => {
callback && callback(data);
});
}
};
$off(eventName) {
if (eventName) {
this.events[eventName] && (delete this.events[eventName]);
} else {
this.events = [];
}
}
}
var event = new EventBus();
event.$on("resize",(args) => {
console.log("我resized的第一个回调" + args);
})
event.$on("resize",(args) => {
console.log("我resized的第二个回调"+args);
})
event.$emit("resize",2)
console.log(event)
// 我resized的第一个回调2
// 我resized的第二个回调2
// EventBus {
// events: { resize: [ [Function (anonymous)], [Function (anonymous)] ] }
// }
17.实现Promise.retry(fn,time);实现超时重传
/**
*
* @param PromiseFn
* @param time
* @returns {Promise<unknown>}
*/
Promise.retry = function(PromiseFn,time) {
return new Promise((resolve, reject) => {
const fn = function(){
PromiseFn().then(res => {
resolve(res)
}).catch(err => {
if(time){
console.log(`倒数第${time}次重试`);
time--;
fn()
}else{
console.log('重试次数使用完毕,依然失败');
reject(err)
}
})
};
fn();
})
};
let a = function () {
return new Promise((res, rej) => {
let num = Math.random() * 10;
num < 2 ? res('数字小于5,成功') : rej('数字大于5,失败');
})
}
Promise.retry(a, 3).then(res => {
console.log(`res:${res}`);
}).catch(err => {
console.log(`err:${err}`);
})
18.Array.isArray()的polyfill
Array.myIsArray = (arg) => {
return Object.prototype.toString.call(arg) === '[object Array]'
}
console.log(Array.myIsArray([1,2,3]))