JS重写内置call

关于call笔者之前在JS中THIS相关问题梳理这篇文章中已经讲过,但笔者觉得之前写的call方法不够惊艳😺,还有很多问题没有考虑到,这次重新整理一下,希望对您有帮助;

let func = function (x, y) {

console.log(this);

return x + y;

};

window.name = "HELLO~";

let obj = {

name: '小芝麻'

};

func(10, 20); //=>this:window 'HELLO~' 30

obj.func(10, 20); //=>Uncaught TypeError: obj.func is not a function

复制代码

需求:让func执行,需要让方法中的this变为objfuncobj本身还没啥关联)

// 实现思路:让func和obj关联在一起

// 1.给obj设置一个属性$func,让其属性值是函数func

// 2.obj.$func() 相当于把func执行了,此时方法中的this就是obj

// 3.这种操作方式会存在一些安全隐患:如果原有obj对象中就有$func的属性,我们设置的这个属性会覆盖原有的属性值[真实操作中,我们尽可能保证这个属性名的唯一性];我们设置的属性,在用完后,还要把它移除掉,因为人家对象原本是没有这个属性的;

// obj.$func = func;

// obj.$func(10, 20); //=>this:obj '小芝麻' 30

// delete obj.$func;

// console.log(obj);

复制代码

代码实现

// 为了让每一个函数都可以调取这个方法了

Function.prototype.changeThis = functionchangeThis(context, ...args) {

// THIS:当前要执行并且改变THIS指向的函数

// CONTEXT特殊情况的处理:不传递是window,传递null/undefined也让其是window,传递非对象或者函数类型值,我们需要让其变为对象或者函数

context == null ? context = window : null;

//=> 为了过滤出传入参数是基本类型的情况

if (typeof context !== "object" && typeof context !== "function") {

//=> 运用构造函数常见一个基本数据类型的实例;

//=> 目的是为了在下面context[uniqueKey] 时,由于基本数据类型不能运用对象的“点”或者“[]”存储属性时报错的问题

context = new context.constructor(context);

}

//=> 利用模版字符串和时间戳生成一个唯一的属性名

let uniqueKey = `?${newDate().getTime()}`;

//=> 给参数中新增个uniqueKey属性与调用的函数关联

context[uniqueKey] = this;

//=> 让调用的函数执行

let result = context[uniqueKey](...args);

//=> 删除新增的属性

delete context[uniqueKey];

//=> 把函数执行的结果 return 出去

return result;

};

let result = func.changeThis(obj, 10, 20);

let result = func.changeThis();

let result = func.changeThis(null/undefined);

let result = func.changeThis(10, 20); //=>方法执行,方法中的THIS是10,给方法传递了20(第一个参数是我们要改变的THIS指向问题)

复制代码

去除注释后的完整代码

Function.prototype.changeThis = functionchangeThis(context, ...args) {

context == null ? context = window : null;

if (typeof context !== "object" && typeof context !== "function") {

context = new context.constructor(context);

}

let uniqueKey = `?${newDate().getTime()}`;

context[uniqueKey] = this;

let result = context[uniqueKey](...args);

delete context[uniqueKey];

return result;

};

let result = func.changeThis(obj, 10, 20);

let result = func.changeThis();

let result = func.changeThis(null/undefined);

let result = func.changeThis(10, 20); //=>方法执行,方法中的THIS是10,给方法传递了20(第一个参数是我们要改变的THIS指向问题)

复制代码

重写内置call

以上是 JS重写内置call 的全部内容, 来源链接: utcz.com/a/115708.html

回到顶部