bind、call、apply
bind、call、apply
作用
都是为了修改执行函数的 this 指向。
区别
bind 只是修改了 this 的指向,没有立即执行,call 和 apply 会立马执行;
call 和 apply 区别在于第二个参数,call 为多个参数展开,apply 的第二参数为一个数组。
实现手写
// _bind.js
// 别人写法
Function.prototype._bind1 = function (context, ...args) {
if (!context || context === null) context = window;
const fn = Symbol();
context[fn] = this;
const _this = this;
const result = function (...innerArgs) {
if (this instanceof _this) {
this[fn] = _this;
this[fn](...[...args, ...innerArgs]);
delete this[fn];
} else {
context[fn](...[...args, ...innerArgs]);
delete context[fn];
}
};
result.prototype = Object.create(this.prototype);
return result;
};
// 官方写法
Function.prototype._bind2 = function () {
const _this = this;
const realThis = arguments[0] ? arguments[0] : window;
const restParams = arguments && arguments.slice(1);
if (typeof _this !== 'function') {
throw new TypeError('Function.prototype.bind - ' + 'what is trying to be bound is not callable');
}
return function () {
_this.call(realThis, ...restParams);
};
};
/*
将函数设为对象的属性
执行该函数
删除该函数
*/
Function.prototype._call = function () {
if (typeof this !== 'function') {
throw new TypeError('must be a function ');
}
const _this = arguments[0] || window; // 获取this参数,如果没有参数或者参数为null时,this指向window
const params = arguments.slice(1); // 获取函数执行的参数。
const fn = new Symbol(); // 唯一性
_this[fn] = this;
const ret = _this[fn](...params); // 带参数执行,
delete _this[fn]; // 删除替代属性
return ret; // 返回执行结果。
};
Function.prototype._apply = function () {
if (typeof this !== 'function') {
throw new TypeError('must be a function ');
}
const _this = arguments[0] || window; // 获取this参数,如果没有参数或者参数为null时,this指向window
const params = arguments.slice(1) || []; // 获取函数执行的参数。
const fn = new Symbol(); // 唯一性
_this[fn] = this;
const ret = _this[fn](params); // 带参数执行,
delete _this[fn]; // 删除替代属性
return ret; // 返回执行结果。
};