前言:锻炼自己的思想,规范自己的编程思路。
问题:
增强所有函数,使其具有 callPolyfill 方法。该方法接受一个对象 obj 作为第一个参数,以及任意数量的附加参数。obj 成为函数的 this 上下文。附加参数将传递给该函数(即 callPolyfill 方法所属的函数)。
例如,如果有以下函数:
function tax(price, taxRate) {
const totalCost = price * (1 + taxRate);
console.log(The cost of ${this.item} is ${totalCost});
}
调用 tax(10, 0.1) 将输出 "The cost of undefined is 11" 。这是因为 this 上下文未定义。
然而,调用 tax.callPolyfill({item: "salad"}, 10, 0.1) 将输出 "The cost of salad is 11" 。this 上下文被正确设置,函数输出了适当的结果。
请在不使用内置的 Function.call 方法的情况下解决这个问题。
示例:(放代码里面)
输入:
fn = function add(b) {
return this.a + b;
}
args = [{"a": 5}, 7]
输出:12
解释:
fn.callPolyfill({"a": 5}, 7); // 12
callPolyfill 将 "this" 上下文设置为 {"a": 5} ,并将 7 作为参数传递。
思路:
callPolyfill函数接受两个参数:context 是要在其中调用函数的上下文对象,args 是一个数组,包含要传递给函数的参数。
函数首先创建一个唯一的 Symbol 键 key,并将其添加到context.__protot 对象上,将其值设置为当前函数(即 this)。然后,使用 context[key] 来调用函数,并传递给定的参数。最后,删除添加的键并返回函数调用的结果。
需要注意的是,这段代码使用了非标准的 proto 属性来访问对象的原型。这个属性并不是所有浏览器都支持的,不建议在生产环境中使用。如果想要访问或设置对象的原型,可以使用标准的 Object.getPrototypeOf() 和 Object.setPrototypeOf() 方法。
基于上述思考,代码如下:
/**
* @param {Object} context
* @param {any[]} args
* @return {any}
*/
Function.prototype.callPolyfill = function(context, ...args) {
const key = Symbol('key')
context.__proto__[key] = this
const res = context[key](...args)
delete context.__proto__[key]
return res
}
/**
* function increment() { this.count++; return this.count; }
* increment.callPolyfill({count: 1}); // 2
*/