坎坎坷坷一路走来,js基础知识大部分停留在了会用阶段,其中实现原理反而似懂非懂的了,加上近几年大环境特别差,危机感特别强,故重新整理学习一遍js基础知识,本篇文章记录js显示绑定this的三种方式,就是call,apply以及bind函数。
我们先先说下三个函数的区别:
-
call: call 函数第一个参数是新this的对象,后面跟着的是参数列表, call(this, arg1,arg2,arg3,..);
-
apply: apply 与 call 相同,不同点在于 call 第一个参数后面跟着的是参数列表,而 apply 第一个参数后是参数数组,apply(this, [arg1,arg2,...]);
-
bind: bind 函数接受参数方式与 call 相同,不同于 call 和 apply 的点在于, call 和 apply 会立即执行函数,而 bind 会返回一个新函数,需要手动调用。let newFun = fn.bind(this, arg1, arg2, ...);
下面我们手动模拟一下这三个函数的实现:
1. call 模拟
Function.prototype.myCall = function() {
if(typeof this !== 'function' ) throw TypeError('not a function');
const [context, ...args] = [...arguments]
context = context || window;
context.fn = this;
let res = context.fn(...args);
delete context.fn;
return res;
}
2. apply 模拟
Function.prototype.myApply = function(context) {
if(typeof this !== 'function' ) throw TypeError('not a function');
context = context || window;
context.fn = this;
let args = [].prototype.slice.call(arguments ,1);
let res = context.fn(args);
delete context.fn;
return res;
}
3. bind 模拟
Function.prototype.myBind = function(context) {
if(typeof this !== 'function' ) throw TypeError('not a function');
let _this = this;
let args = [].prototype.slice.call(arguments, 1);
function TempFun () {};
let bindFun = function() {
let bindArgs = [].prototype.slice.call(arguments);
return _this.apply(this instanceof bindFun ? this : context, args.concat(bindArgs));
}
TempFun.prototype = this.prototype;
bindFun.prototype = new TempFun();
return bindFun;
}
OK,今天的基础复习结束。有问题欢迎大家指出,谢谢~