本次手写相对于上一次做了一些优化
1.当传入的参数的null和undefined时,this指向为全局(兼容浏览器环境和node环境)
2.使用symbol修饰符作为唯一标识
Function.prototype.myCall2 = function (context, ...args) {
//context为传入的对象 ...args为传入的剩余参数 这里运用了es6的剩余参数比较方便
//注意点1:globalThis既存在于node环境又存在于浏览器环境,二者环境兼容该方法才无可挑剔
context === undefined || context === null
? (context = globalThis)
: Object(context);
//注意点2:使用es6的symbol数据类型可以使新建的函数唯一,避免覆盖掉原对象中的属性
let key = Symbol("temp");
//将this(此时的this指向对调用的对象)挂载到fn属性上
//最好不要这样(context.fn = this)定义属性,会导致原属性被覆盖
//这里使用es5的Object.defineProperty为context定义属性
Object.defineProperty(context, key, {
enumerable: false,
value: this,
});
//执行fn函数并传入剩余参数得到结果
let result = context[key](...args);
//将fn属性从context对象中删除
delete context[key];
//返回result
return result;
};