代码如下
Function.prototype.call = function call(context, ...params) {
// 这里的this 是指向的这个函数
let self = this,
key = Symbol("KEY"), // 用Symbol 是为了拿到唯一的key
result;
// 在 == 的情况下 undefined 跟null 也是相等的
if(context == null) context = window;
// 在context 不等于 对象跟函数时, Object 可以把传入的值 转化成一个它对应的类型值, 下面会说明
// if(!/^(object|function)$/i.test(typeof context)) context = Object(context);
context[key] = self;
// 这个代码 才是精髓 这个是利用了this的特点 谁调用 那么我的this 就指向谁
result = context[key](...params);
// 这里再 删除 添加过的key
delete context[key]
return result;
}
// 这个就是 为什么 要用Object 包裹一下的原因, 如果不包裹 那么我们传入进来的10 就没有办法添加他的属性key 做操作了
简单的实现一下 bind方法
Function.prototype.bind = function bind(context, ...params) {
// 这里的this 指向的是这个 func
let self = this;
return function(...args) {
// 通过 apply 来改变 this的指向
return self.apply(context, params.concat(args));
}
}
this的理解
1.this 遵循一个规则,就是谁调用它 他就指向谁, 默认情况下是指向Window,再严格模式下是undefined
2. 再当前元素的事件绑定方法,方法中的this就是当前元素本身
3. 构造函数中的this就是当前的实例
4. 箭头函数中的this指向就是他所在的上下文中的this