[javascript核心-19] 前端常见手写代码实现🦅
本文github地址:JavaScript_Everything 大前端知识体系与面试宝典,从前端到后端,全栈工程师,成为六边形战士
柯里化函数
如何实现一个通用的柯里化函数?
- 需要接收一个需要柯里化的函数
- 需要存放每一次函数调用的参数
- 对参数进行判断:如果参数数目不够原函数的参数数目,不调用原函数,返回新的函数继续接收下一个参数;反之则调用函数
作用:
- 参数复用,逻辑复用
- 延时计算,延时执行
function add(num1,num2, num3, num4, num5){
return num1+num2+ num3+ num4+ num5
}
function curry(fn){
let self = this
return function curried(...args){
if(args.length >= fn.length){
return fn.apply(self, args)
}else{
return function(...otherArgs){
return curried.apply(self, [...args, ...otherArgs])
}
}
}
}
let newAdd = curry(add)
console.log(newAdd(20 ,30,40,50,60))
console.log(newAdd(20)(30,40,50,60))
console.log(newAdd(20)(30,40)(50,60))
console.log(newAdd(20,30,40)(50,60))
函数组合
利用数组的reduce
方法,将多个函数进行组合
function add(num1){
return num1+1
}
function double(num1){
return num1 * 2
}
function compose(...fns){
return function(arg){
return fns.reduce((prev, fn)=>{
return fn(prev)
},arg)
}
}
let newFn = compose(double,add)
console.log(newFn(10))
考虑一些优化的情况:
- 如果给组合函数参数列表传入的函数个数为 0,则直接返回调用时的值
- 如果组合函数参数列表只接收到了一个函数,则直接执行该函数,不必进行
reduce
处理
function add(num1){
return num1+1
}
function double(num1){
return num1 * 2
}
function compose(...fns){
if(fns.length === 0) return arg => arg
if(fns.length === 1) return fns[0]
return function(arg){
return fns.reduce((prev, fn)=>{
return fn(prev)
},arg)
}
}
let newFn = compose(double,add)
console.log(newFn(10)) // 21
let newFn2 = compose()
console.log(newFn2(10)) // 10
let newFn3 = compose(double)
console.log(newFn3(10)) // 20
还可以写的更简洁一些:
function compose(...fns){
if(fns.length === 0) return arg => arg
if(fns.length === 1) return fns[0]
return fns.reduce((result, fn) => (...args) => result(fn(...args)))
}
实现new
- 要实例化出一个对象
- 实例化出的对象内部的this应该指向实例对象
- 应该将实例化对象的隐式原型指向构造函数的原型对象
- 构造函数如果有返回值,那构造函数的返回值,就是实例化对象的返回值
- 如果构造函数无返回值,则返回空对象
const ObjectFactory = (...args) => {
// 1.初始化对象
const obj = {}
// 2.获取到构造函数
const constructor = [].shift.call(args)
// 3.指定原型
obj.__proto__ = constructor.prototype
// 4.将构造函数内部的this指向实例对象,并执行构造函数
const res = constructor.apply(obj, args)
// 5.保证返回的是对象,如果构造函数无返回值则返回空对象
return typeof res === 'object' ? res : obj
}
function Person(name,age){
this.name = name;
this.age = age;
return {
name: this.name,
age: this.age,
}
}
function Person2(name,age){
this.name = name;
this.age = age;
}
const obj = ObjectFactory(Person, 'flten', 24)
console.log(obj) // { name: 'flten', age: 24 }
const obj2 = ObjectFactory(Person2, 'flten', 24)
console.log(obj2) // Person2 { name: 'flten', age: 24 }
实现instanceof
instanceof的作用:检测某构造函数的原型对象是否出现在实例对象的原型链上
function Person(name,age){
this.name = name;
this.age = age;
}
const obj = new Person()
console.log(obj instanceof Person) // true
实现的关键点:
- 获取实例对象的隐式原型
- 获取构造函数的原型对象
- 通过while循环不断向上查找实例对象的原型链
- 对比是否和构造函数的原型对象相同
- 如果直到原型链为null,则返回false
- 如果出现相同的情况,返回true
实现 instanceof
/**
*
* @param {*} Obj 要检测的对象
* @param {*} Constructor 目标构造函数
* @returns boolean
*/
function instanceOf(Obj, Constructor){
let ObjProto = Obj.__proto__
const ConstructorPrototype = Constructor.prototype
while(true){
if(Object.is(ObjProto, null)){
return false
}else if(Object.is(ObjProto, ConstructorPrototype)){
return true
}
ObjProto = ObjProto.__proto__
}
}
function Person(name,age){
this.name = name;
this.age = age;
}
const p = new Person()
console.log(instanceOf(p, Person)) // true
console.log(instanceOf(p, Object)) // true
console.log(instanceOf('a', Person)) // false
本文github地址:JavaScript_Everything 大前端知识体系与面试宝典,从前端到后端,全栈工程师,成为六边形战士
转载自:https://juejin.cn/post/7249646017864302647