携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第31天,点击查看活动详情
前言
createBind方法可以创建一个包装func
的函数,用可选的this
调用它。
参数说明:
- 参数1:函数类型,表示要包装的函数。
- 参数2:数字类型,表示位掩码标志。
- 参数3:表示参数1
func
的this
绑定。
createBind方法在实现上借助了内部封装的createCtor方法。
createCtor
createCtor方法返回新的包装函数,该方法接收一个函数类型的参数,表示构造要包装的构造函数。
该方法在实现上借助isObject判断方法判断对象类型的数据,同时借助baseCreate方法绑定指定原型。实现上通过switch进行匹配,参数长度为7或7以内的,都返回new Ctor的结果,否则会判断是否是对象类型,是的话返回通过apply方法调用和传参的结果,不是对象类型的话则返回baseCreate的调用结果。
源码如下:
import baseCreate from './_baseCreate.js';
import isObject from './isObject.js';
function createCtor(Ctor) {
return function() {
var args = arguments;
switch (args.length) {
case 0: return new Ctor;
case 1: return new Ctor(args[0]);
case 2: return new Ctor(args[0], args[1]);
case 3: return new Ctor(args[0], args[1], args[2]);
case 4: return new Ctor(args[0], args[1], args[2], args[3]);
case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]);
case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]);
case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
}
var thisBinding = baseCreate(Ctor.prototype),
result = Ctor.apply(thisBinding, args);
return isObject(result) ? result : thisBinding;
};
}
baseCreate
baseCreate方法相当于Object.create方法,baseCreate方法的实现是对Object.create方法的扩展和兼容。该方法接受一个对象类型的参数,表示proto要从中继承的对象。
实现上借助isObject判断方法,如果参数不是对象类型则返回空对象。如果当前支持Object.create方法则返回Object.create的调用结果。否则则通过prototype的直接设置去更改原型的继承关系。
源码如下:
import isObject from './isObject.js';
var objectCreate = Object.create;
var baseCreate = (function() {
function object() {}
return function(proto) {
if (!isObject(proto)) {
return {};
}
if (objectCreate) {
return objectCreate(proto);
}
object.prototype = proto;
var result = new object;
object.prototype = undefined;
return result;
};
}());
源码实现
createBind方法实现上返回一个新的函数,该函数内部对参数及进行判断。
先对函数参数func进行初始化只有this存在并且this不等于全局环境,并且this不在wrapper的原型链上,会对func初始化为createCtor(func)的调用,否则直接初始化为参数func。
this的绑定则通过apply方法,对于绑定的this,会通过isBind判定,是的话绑定为参数thisArg,否则绑定当前this。
源码如下:
import createCtor from './_createCtor.js';
import root from './_root.js';
var WRAP_BIND_FLAG = 1;
function createBind(func, bitmask, thisArg) {
var isBind = bitmask & WRAP_BIND_FLAG,
Ctor = createCtor(func);
function wrapper() {
var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
return fn.apply(isBind ? thisArg : this, arguments);
}
return wrapper;
}
小结
本篇章通过createBind方法的实现,同时了解到createCtor内部方法和baseCreate内部方法的实现,了解到了lodash内部对于绑定this的处理和Object.create的兼容处理等。