建p2p网站,openshift安装wordpress密码忘记,wordpress扩展字段,网页布局有哪些手写实现call#xff0c;apply和bind方法
call#xff0c;apply和bind方法均是改变this指向的硬绑定方法#xff0c;要想手写实现此三方法#xff0c;都要用到一个知识点#xff0c;即对象调用函数时#xff0c;this会指向这个对象#xff08;谁调用this就指向谁#…手写实现callapply和bind方法
callapply和bind方法均是改变this指向的硬绑定方法要想手写实现此三方法都要用到一个知识点即对象调用函数时this会指向这个对象谁调用this就指向谁
先设定一个测试函数及测试对象
function func(num1, num2) {console.log(this:, this)return num1 num2
}const testObj {test: 测试用的对象
}手写实现call方法
自己写的所以把方法名定义为myCall。实现func的this指向testObj,输出num1 num2的值。 测试用例
const res func.myCall(testObj, 1, 2);
console.log(res:, res);
// 输出this是{ test: 测试用的对象 }
//num1 num2 计算结果 3第一步要实现任何函数都能使用这个myCall方法则该方法需要定义在原型上面因此:
Function.prototype.myCall function(thisArg, ...args) {
}
// thisArg -- 待绑定this的参数对象。
// args -- 待传入的参数
// 因为call传入参数是挨个传入所以用rest参数方法...args第二步 设置this并调用原函数
Function.prototype.myCall function (thisArg, ...args) {const key Symbol(key);thisArg[key] this; // 步骤aconst res thisArg[key](...args); // 步骤bdelete thisArg[key] // 步骤creturn res
}步骤a解释 给传入的thisArg对象添加一个过渡性的属性此处用Symbol因为Symbol具有唯一性不会与thisArg里的属性发生重名覆写的情况。步骤a的this是原函数本例中是func。因为执行func.myCall()时根据谁调用this就指向谁的原则myCall()里的this即指向func。因此步骤a最终是往thisArg中添加了原函数func。
步骤b解释 执行thisArg中刚刚添加的函数func。依旧是谁调用this指向谁的原则func的this就指向的thisArg。
步骤c解释删除掉无意义的过渡性属性。
所以上述测试用例中thisArg – testObjnum1 – 1, num2 – 2结果打印如下
手写实现apply方法
apply方法和call方法区别在于传入参数是个数组。其余实现原理相同。所以实现代码
Function.prototype.myApply function (thisArg, args) {const key Symbol(key);thisArg[key] this; const res thisArg[key](...args); delete thisArg[key] return res
}const res func.myApply(testObj, [1, 2]);
console.log(res:, res);
// 输出this是{ test: 测试用的对象 }
//num1 num2 计算结果 3手写实现bind方法
bind方法和call方法不同点在于bind返回的是个函数。所以实现代码如下
Function.prototype.myBind function (thisArg, ...args) {return (...args2) { // 允许调用的时候继续传入参数const key Symbol(key);thisArg[key] this; // 箭头函数中this是定义时的this也就是myBind的thisconst res thisArg[key](...args, ...args2)delete thisArg[key]return res}
}const res func.myBind(testObj, 1);
console.log(res:, res(2));结果 简而言之bind可以理解为返回一个函数返回的函数中使用call改变了this指向。