js中改变this指向一般有三种方式
- 隐式转化
- 显示转化
- 通过new关键字
显示转化主要是通过call,apply,bind方式来实现。下面介绍这三个方法实现的基本原理。
Call实现
Function.protorype.myCall = function(context) {
if(typeof context !== 'function') {
throw new Error('not function');
}
const args = [...arguments].slice(1);
context = context || window;
context.fn = this;
const result = context.fn(...args);
delete context.fn;
return result;
}
Apply实现
Function.protorype.myApply = function(context) {
if(typeof context !== 'function') {
throw new Error('not function');
}
const args = arguments[1]
const fnSymbol = Symbol()
context = context || window;
context[fnSymbol] = this;
let result = null;
if(args) {
result = context[fnSymbol](...args);
} else {
result = context[fnSymbol]();
}
delete context[fnSymbol];
return result;
}
Bind实现
bind返回的是一个函数。
Function.prototype.myBind = function (context) {
// 判断调用对象是否为函数
if (typeof this !== "function") {
throw new Error("Type error");
}
// 获取参数
const args = [...arguments].slice(1),
const fn = this;
return function Fn() {
return fn.apply(
this instanceof Fn ? this : context,
// 当前的这个 arguments 是指 Fn 的参数
args.concat(...arguments)
);
};
};