js手写方法之--call/apply/bind
程序员文章站
2022-07-14 14:27:10
...
call的实现
其一:使用ES6的语法
/**
* 核心思想:
* 1. 绑定当前方法到 context 对象上
* 这样,执行context.fn()时,内部的this就指向了context
* 2. 使用ES6新特性,展开运算符
*/
Function.prototype.mycall (context, ...args) {
// 若context不存在,则取 context = window
context = Object(context) || window
// 绑定当前方法 this 到 context上
// 此时context.fn(...args) === this.call(context, ...args)
context.fn = this
let result = context.fn(...args)
// 方法执行完成后,删除context.fn
delete context.fn
return result
}
其二:不使用ES6语法
/**
* 不使用ES6语法的写法,核心就是eval()
* 构造字符串 "context.fn(arguments[1], arguments[2])"
* 用eval调用
*/
Function.prototype.mycall = function (context) {
context = Object(context) || window;
let _args = [];
context.fn = this;
for (let i = 1, l = arguments.length; i < l; i++) {
_args.push('arguments[' + i + ']');
}
// result = eval('context.fn(arguments[1], arguments[2])')
let result = eval('context.fn(' + _args.join(',') + ')');
delete context.fn;
return result;
}
apply的实现
/**
* 核心思想和call一致
*/
Function.prototype.myapply = function (context, args = []) {
context = Object(context) || window
context.fn = this
let result = context.fn(...args)
delete context.fn
return result
}
bind的实现
/**
* bind稍微复杂点,需要实现两点
* 1. 作为方法使用 bindFn(),this 指向 context
* 2. 作为构造函数调用 new bindFn(),this 不指向 context
*/
Function.prototype.mybind = function (context) {
context= Object(context) || window;
let self = this;
// 初始传入的参数
let _args = [].slice.call(arguments, 1);
let _bind = function () {
// 作为方法调用 _bind() 时,this指向他的调用者,window 或是 其他
// 例如:
// myfn = function (){};
// mybindfn = myfn.mybind(context, arg1) === _bind
// mybindfn() ===> _bind()
// 作为构造函数调用时, myobj = new _bind();
// myobj.__proto__ === _bind.prototype === new Fn() === Fn.prototype
// 此时_bind 中的 this 就是 myobj
// 故而 myobj instanceof Fn === true
let _this = this instanceof Fn ? this : context;
return self.apply(_this, _args.concat([].slice.call(arguments)))
}
// 新建一个空方法 Fn,使 Fn原型链与当前方法的原型链一致
let Fn = function () {};
Fn.prototype = self.prototype;
_bind.prototype = new Fn();
return _bind;
}
上一篇: call,apply,bind
下一篇: linux下创建新用户以及删除