步骤口述参考,实现笔试参考
实现new
步骤
- 创建空对象
- 将构造函数原型复制到创建的对象
- 以空对象为上下文执行构造函数
- 如果构造函数执行返回对象则返回该对象,否则返回创建的对象
实现
function mockNew() {
const obj = {};
const Constructor = [].shift.call(arguments);
obj.__proto__ = Constructor.prototype;
// 第一个传入参数已经shift
const res = Constructor.apply(obj, arguments);
return typeof res === 'object' ? res : obj;
}
实现bind
步骤
- 判断调用bind对象是否是对象
- 创建返回函数,判断是否是new创建
- 将函数的原型绑定到返回函数上
- 返回创建的函数
实现
Function.prototype.mockBind = function(context) {
if (typeof this !== 'function') {
return TypeError('error');
}
const fThis = this;
const bindArgs = [].slice.call(arguments, 1);
const fNop = function() {};
const fBound = function() {
const fnArgs = [].slice.call(arguments);
// this instanceof fBound 说明bind返回函数通过new执行的
return fThis.apply(this instanceof fBound ?
this :
context, bindArgs.concat(fnArgs));
}
if(this.prototype) {
fNop.prototype = this.prototype;
}
/**
* 断开fBound原型和this原型上方法,
* 如果fBound.prototype = this.prototype
* 那么fBound原型上添加方法,this的原型上也会有
*/
fBound.prototype = new fNop();
// 以上效果同:fBound.prototype.__proto__ = fNop.prototype
return fBound;
}
实现apply
步骤
- 获取参数作为上下文context,为空默认值window
- 把this方法作为属性绑到上下文context
- 以context执行挂载的this方法
- 删除挂载属性,返回执行结果
实现
function mockApply(context) {
const ctx = context || window;
ctx.fn = this;
const args = arguments[1];
let res = undefined;
if(args) {
res = ctx.fn(...args);
} else {
res = ctx.fn()
}
delete ctx.fn;
return res;
}
实现call
步骤
- 步骤同上,只是参数不一样,获取时候方式不同
实现
function mockCall(context) {
const ctx = context || window;
ctx.fn = this;
const args = [...arguments].slice(1);
const res = ctx.fn(...args);
delete ctx.fn;
return res;
}