// 使用原型链,将_call存在Function.prototype中,这样所有函数调用时都可以使用到_call
Function.prototype._call = function(context, ...args)
{
// context可能传入的是null,call的实现中会使得context = globalThis
// JS中的二元运算符||会返回第一个为真值的变量
context = context || globalThis;
/*
我们需要先明白,这里的this到底是什么,那么谁调用了_call,谁就是this
所以this就是调用_call的函数
首先需要明确,我们无法直接使用this(...args),因为这样并没有办法改变
调用_call的函数内部this的指向
此时可以想到,如果我们调用对象的方法,那么这个方法的this是指向对象的
所以我们可以将调用_call的函数作为context的一个属性
然后再调用它,那么就解决了其内部this指向context的问题。
我们之所以大费周章地使用Symbol,是因为我们需要一个和context中任意属性都不重名的属性
Symbol是唯一的。
然后对于这样的一个调用_call的函数,我们可能有返回值,所以必须用变量收集起来。
最后我们从context中删去我们的临时属性。
PS:
如果是一个Symbol类型作为对象的属性的话,只能使用[]来调用和修改它
*/
const key = Symbol();
context[key] = this;
const ret = context[key](...args);
delete context[key];
return ret;
};