call的实现
- 第一个参数为null或者undefined时,this指向全局对象window,值为原始值的指向该原始值的自动包装对象,如 String、Number、Boolean
- 为了避免函数名与上下文(context)的属性发生冲突,使用Symbol类型作为唯一值
- 将函数作为传入的上下文(context)属性执行
- 函数执行完成后删除该属性
- 返回执行结果
Function.prototype.myCall = function (ctx, ...args) {
// 简单处理未传ctx上下文,或者传的是null和undefined等场景
if (!ctx) {
ctx = typeof window !== "undefined" ? window : global;
}
// 暴力处理 ctx有可能传非对象
ctx = Object(ctx);
// 用Symbol生成唯一的key
const fnName = Symbol();
// 这里的this,即要调用的函数
ctx[fnName] = this;
// 将args展开,并且调用fnName函数,此时fnName函数内部的this也就是ctx了
const result = ctx[fnName](...args);
// 用完之后,将fnName从上下文ctx中删除
delete ctx[fnName];
return result;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18