基本介绍
- 在哪:在Function的prototype(原型)上
- 谁能用:函数
- 为啥函数能用:因为所有函数都是Function的实例,所以可以通过__proto__(原型链)找到Function.prototype
- 作用:改变this的指向并且让函数执行
那call内部到底是如何实现的呢?让我们抽丝剥茧,一步一步分析~~~
1、基础款:
let func = function (x, y) {
console.log(this.name, x + y);
};
let obj = {
name: "xiaoxiaohui"
};
window.name = "chengxiaohui";
func();//this指的是window
obj.func();//报错 因为obj里面没有window obj.func-->undefined undefined()报错
/**
* 需求:
* 1、让func执行
* 2、让this指向obj
* 思路:
* func和obj没有关联,那就产生关联(在obj里面有一个键值对,属性值为func这个函数,那obj.xx不就能拿到了吗?
* */
//代码实现:
obj.func = func;
obj.func();
/**
*存在着一定的问题:
*1、如果自己取的属性名和obj里原有的撞名了怎么办?存在一定的安全隐患
*2、obj中多了一个键值对
*/
// let uniqueKey = `$$${new Date().getTime()}`;
let uniqueKey = new Date().getTime();
obj.uniqueKey = func;
obj.uniqueKey(10,20);
delete obj.uniqueKey;
console.log(obj);
复制代码
需求变更:将上述代码封装成一个函数
2、进阶版
let func = function (x, y) {
console.log(this, x + y);
return x - y;
};
let obj = {
name: "xiaoxiaohui"
};
window.name = "chengxiaohui";
function changeThis(func, context, ...args) {
// let args = Array.from(arguments).slice(2);
let uniqueKey = new Date().getTime();
context.uniqueKey = func;
let res = context.uniqueKey(...args);
delete context.uniqueKey
return res
}
let res = changeThis(func, obj, 10, 20)
console.log(res)
复制代码
需求变更://不想把func作为参数传进去 而是想func.changeThis(context,…params)
3、终极版
Function.prototype.changeThis = function (context, ...args) {
context == null ? context = window : null;
if (typeof context !== "object" && typeof context !== "function" && typeof context !== "bigInt") {
context = new context.constructor(context);
};
// let args = Array.from(arguments).slice(2);
let uniqueKey = new Date().getTime();
context.uniqueKey = this;
let res = context.uniqueKey(...args);
delete context.uniqueKey;
return res
};
// let res = func.changeThis(obj, 10, 20);
// let res = func.changeThis();
// let res = func.changeThis(undefined/null);
let res = func.changeThis(10, 20);//this 是10
复制代码
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END