bind
bind 可以看作是 js 中的部分应用(partical), 调用的方式为:
function.bind(this, args1, args2, ..., argsn)
我们知道 function.length 返回的为 函数声明的形参个数,而 bind 返回函数同样遵循这个原则,例如:
function add(x, y, z){
return x + y + z
}
const add1 = add.bind(null, 1, 2, 3, 4)
console.info(add.length, add1.length) // 3, 2
利用这个特性,我们可以直接实现一个 currying 函数:
function currying(func){
return function() {
if(func.length === arguments.length){ // 当传入的参数个数 = 形参个数,则直接调用
return func(...arguments)
}else{
return currying(func.bind(this,...arguments)) // 否则继续 currying
}
}
}
const add = currying((x, y, z) => x + y + z)
console.info(add(1, 2, 3)) // 6
console.info(add(1)(2)(3)) // 6
实现一个 new
首先看 js 中的 new 做了什么事情:
- 创建一个空的简单 JavaScript 对象(即
{}); - 为步骤 1 新创建的对象添加属性
__proto__,将该属性链接至构造函数的原型对象 ; - 将步骤 1 新创建的对象作为
this的上下文 ; - 如果该函数没有返回对象,则返回
this。
按照这个步骤写代码即可:
function New(constructor, ...args){
const This = {}
Object.setPrototypeOf(This, constructor.prototype)
const res = constructor.call(This, ...args)
return res instanceof Object ? res : This
}
function People(name){
this.name = name
}
console.info(New(People, "lily")) // { name: 'lily' }
实现 instanceof
obj instanceof Type 可以看作 Object.getPrototypeOf(obj) === Type.prototype。因此只要递归往上查找,找到返回 true,找不到返回 false 即可:
function Instanceof(obj, Type){
let prototype = Object.getPrototypeOf(obj)
while(prototype != null){
if(prototype === Type.prototype){
return true;
}
prototype = Object.getPrototypeOf(prototype)
}
return false
}