本猿学习掌握了关于改变this指向的三个函数,今天写下一篇自己的博客记录来让我更加记忆深刻哈哈哈哈哈哈哈。
例个模型:oldThis.call(newThis)
先来说一下改变this指向的思路:
- 给newThis对象加一个属性(这个属性不可以与newThis对象原有的属性名冲突),然后这个属性的属性值是oldThis。
- 调用这个属性,调用的时候由于是在newThis对象下调用,所以this指向了newThis,这就达到了调用oldThis时,其中的this指向的是newThis了。
三个改变this指向的函数,先说call和apply,它们在改变this指向的同时调用它的函数是会执行的。
模拟封装call方法,参数是排在this后面一一列举出来的:
Function.prototype.myCall = function(newThisObj){
// 如果调用myCall的不是函数则会报错
if(typeof this != "function"){
throw new TypeError("Error");
}
newThisObj = newThisObj || globalThis; // 你给我的乱七八糟的我就指向window
newThisObj.random = this; // 给它一个属性,属性值为原函数
const args = [...arguments].slice(1); // 把第一个参数this裁掉
const result = newThisObj.random(...args); // 以newThisObj身份调用原函数,this指向就是newTHisObj啦
delete newThisObj.random; // 给人家新增了一个属性,用完就删了哦
return result;
}
模拟封装apply方法,参数是以第二个参数(数组)呈现出来的:
Function.prototype.myApply = function(newThisObj){
if(typeof this !== "function"){
throw new TypeError("Error");
}
newThisObj = newThisObj || globalThis;
newThisObj.random = this;
let result;
if(arguments[1]) result = newThisObj.random(...arguments[1]);
else result = newThisObj.random();
delete newThisObj.random;
return result;
}
bind只是改变this指向,但函数不会执行,返回值时改变this指向后的新函数。bind时,后面接了几个实参,调用新函数时,实参要从形参头部砍去多少个。
Function.prototype.myBind = function (context) {
if(typeof this !== 'function'){
throw new TypeError('Error');
}
const _this = this; // 使用一个变量存储一下当前this
const args = [...arguments].slice(1);
return function F(){
// 因为返回了一个函数,直接调用指向全局window,使用new调用就是实例化对象了,需要判断一下
// 返回的函数,会以new形式调用,或者直接加()调用
if(this instanceof F){
return new _this(...args, ...arguments);
}
return _this.apply(context, args.concat(...arguments));
}
}
以上就是我学习总结的关于改变this指向的函数实现方法啦!把自己的成长印记刻在这里^ . ^