bind & call & apply
2021-09-09 本文已影响0人
菜鸡前端
网上很多文章 apply 的写法是错误的,Function.prototype.apply 第二个参数必须为1个数组,拍平后传给函数实例。
1. bind
Function.prototype.bind = function(context, ...args) {
if (typeof this !== 'function') {
throw new Error("Type Error");
}
var self = this;
return function F() {
// 考虑 new 操作符
if(this instanceof F) {
return new self(...args, ...arguments)
}
return self.apply(context, [...args, ...arguments])
}
}
2. call
Function.prototype.myCall = function (context, ...args) {
if (context === null || context === undefined) {
// 指定为 null 和 undefined 的 this 值会自动指向全局对象
context = window
} else {
// 值为原始值(数字,字符串,布尔值)的 this 会指向该原始值的实例对象
context = Object(context)
}
const key = Symbol();
context[key] = this;
const res = context[key](...args);
delete context[key];
return res;
}
// 用例
function fn(a) {
console.log(this, a)
}
fn.myCall({ name: 1 }, 2)
3. apply
Function.prototype.myApply = function (context, args) {
if (context === null || context === undefined) {
// 指定为 null 和 undefined 的 this 值会自动指向全局对象
context = window
} else {
// 值为原始值(数字,字符串,布尔值)的 this 会指向该原始值的实例对象
context = Object(context)
}
const key = Symbol();
context[key] = this;
const res = (context[key])(...args);
delete context[key];
return res;
}
// 用例
function fn(a) {
console.log(this, a)
}
fn.myApply({ name: 1 }, [2])