js new call apply bind 的 原理

时间:2023-02-01 00:23:18

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);
}
}