小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
手撕面试题之 new操作符、instanceof操作符、函数柯里化、函数组合
new操作符
const _new = function _new(Ctor,...params){
// 格式校验:函数 & 有原型对象 & 不是Symbol/BigInt
if(typeof Ctor !== 'function') throw new TypeError(`${Ctor} is not a constructor`)
let name = Ctor.name,
proto = Ctor.prototype
if(/^(Symbol|BigInt)$/i.test(name) || !proto) throw new TypeError(`${name} is not a constructor`)
// 创建一个当前类的实例对象
let obj = Object.create(Ctor.prototype)
// 把构造函数像普通函数一样执行,但是this需要指向创建的实例对象
let result = Ctor.call(obj,...params)
// 看函数的返回值,如果没有写返回值,或者返回的是原始值,我们默认返回实列对象;如果返回的是对象,则以自己返回的为主
if(result !== null && /^(object|function)$/i.test(typeof result)) return result
return obj
}
instanceof操作符
- 可以参考文章了解instanceof的原理数据类型检测的四种方法及其原理
const instance_of = function instance_of(obj, Ctor) {
if(Ctor == null) throw new TypeError('Right-hand side of instanceof is not a object')
if (typeof Ctor !== 'function') throw new TypeError('Right-hand side of instanceof is not callable')
if (!Ctor.prototype) throw new Error('Function has non-object prototype undefined in instanceof check')
if(obj == null || !/^(object|function)$/.test(typeof obj)) return false
if(typeof Ctor[Symbol.hasInstance] === 'function') return Ctor[Symbol.hasInstance](obj)
let proto = Object.getPrototypeOf(obj)
while (proto) {
if(proto === Ctor.prototype) return true
proto = Object.getPrototypeOf(proto)
}
return false
}
函数柯里化
预先存储(预处理),利用闭包的"保存机制",我们把一些值事先存储起来,供其下级上下文中后期使用.
const curry = function curry(func){
if(typeof func !== 'function') throw new TypeError(`${func} is not a function`)
return function curried(...params) {
if (params.length < func.length) {
return function(...args){
return curried(...params.concat(args))
}
}
return func(...params)
}
}
函数组合
如果一个函数要经过多个函数处理才能得到最终值(类似这样h(g(f(x)))),这个时候可以把中间 过程的函数合并成一个函数,函数就像是数据的管道,函数组合就是把这些管道连接起来,让数据穿过多个管道形成最终结果,函数组合默认是从右到左执行。
const compose = function compose(...funcs){
let len = funcs.length
if(len === 0) x => x
if(len === 1) return funcs[0]
return function operate(x){
return funcs.reduceRight((memo, func) => {
return func(memo)
}, x)
}
}