new
new 做了什么事?
1. 以 Object.protoype 为原型创建一个新对象
2. 以新对象为 this,执行函数的 [[call]]
3. 如果 [[call]] 的返回值是对象,那么,返回这个对象,否则返回第一步创建的新对象
function myNew(fn, ...args) { const obj = Object.create(fn.prototype); const ret = fn.call(obj, ...args); return ret instanceof Object ? ret : obj; }
call
实际上就是把方法挂在对象上,执行然后删除
Function.prototype.myCall = function(context, ...args) { if (typeof this !== 'function') { throw new TypeError('this is not a function') } context = context || window; context.fn = this; const ret = context.fn(...args); delete context.fn; return ret }
apply
原理和call一样
Function.prototype.myApply = function (context, arg) { if (typeof this !== 'function') { throw new TypeError('this is not a function') } context = context || window; context.fn = this; let ret; if (arg) { ret = context.fn(...args); } else { ret = context.fn(); } delete context.fn; return ret }
bind
bind原理就是封一层闭包
function.prototype.myBind = function (context, ...bindArgs) { if (typeof this !== 'function') { throw new TypeError('this is not a function'); } const _this = this; return function Fn(...execArgs) { const args = bindArgs.concat(execArgs); return _this.call(this instanceof Fn ? this : context, ...args); } }