2693. 使用自定义上下文调用函数
2693. 使用自定义上下文调用函数
题目
Enhance all functions to have the callPolyfill
method. The method accepts an object obj
as it's first parameter and any number of additional arguments. The obj
becomes the this
context for the function. The additional arguments are passed to the function (that the callPolyfill
method belongs on).
For example if you had the function:
function tax(price, taxRate) {
const totalCost = price * (1 + taxRate);
console.log(`The cost of ${this.item} is ${totalCost}`);
}
Calling this function like tax(10, 0.1)
will log "The cost of undefined is 11"
. This is because the this
context was not defined.
However, calling the function like tax.callPolyfill({item: "salad"}, 10, 0.1)
will log "The cost of salad is 11"
. The this
context was appropriately set, and the function logged an appropriate output.
Please solve this without using the built-in Function.call
method.
Example 1:
Input:
fn = function add(b)
args = [{"a": 5}, 7]
Output: 12
Explanation:
fn.callPolyfill({"a": 5}, 7); // 12
callPolyfill sets the "this" context to {"a": 5}. 7 is passed as an argument.
Example 2:
Input:
fn = function tax(price, taxRate) { return
The cost of the ${this.item} is ${price * taxRate}
; }args = [{"item": "burger"}, 10, 1.1]
Output: "The cost of the burger is 11"
Explanation: callPolyfill sets the "this" context to {"item": "burger"}. 10 and 1.1 are passed as additional arguments.
Constraints:
typeof args[0] == 'object' and args[0] != null
1 <= args.length <= 100
2 <= JSON.stringify(args[0]).length <= 10^5
题目大意
增强所有函数,使其具有 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
方法的情况下解决这个问题。
示例 1:
输入:
fn = function add(b)
args = [{"a": 5}, 7]
输出: 12
解释:
fn.callPolyfill({"a": 5}, 7); // 12
callPolyfill 将 "this" 上下文设置为 {"a": 5} ,并将 7 作为参数传递。
示例 2:
输入:
fn = function tax(price, taxRate) { return
The cost of the ${this.item} is ${price * taxRate}
; }args = [{"item": "burger"}, 10, 1,1]
输出: "The cost of the burger is 11"
**解释:**callPolyfill 将 "this" 上下文设置为 {"item": "burger"} ,并将 10 和 1.1 作为附加参数传递。
提示:
typeof args[0] == 'object' and args[0] != null
1 <= args.length <= 100
2 <= JSON.stringify(args[0]).length <= 10^5
解题思路
要实现 callPolyfill
方法,可以通过将要调用的函数临时添加为对象的一个方法,然后使用这个方法来调用函数。以下是详细的实现思路:
定义
callPolyfill
方法:将其添加到Function.prototype
,使所有函数都能访问这个方法。- 第一个参数是
context
,表示函数调用时的this
上下文。 - 后面的参数是传递给原始函数的参数
args
。
- 第一个参数是
将函数赋值给对象:
- 在
context
中临时创建一个唯一的 Symbol 属性,因为 Symbol 属性在迭代中不可枚举; - 将 Symbol 属性指向要调用的函数,可以使用
this
来引用当前函数。
- 在
调用函数:使用临时创建的方法调用它,传入附加参数。
清理:调用后,从
context
中删除临时属性,确保不会对context
产生影响。返回结果:如果函数有返回值,可以将其返回。
复杂度分析
- 时间复杂度:
O(1)
,只进行了一次函数调用。 - 空间复杂度:
O(1)
,只使用了常数级的空间来存储临时方法和结果。
代码
/**
* @param {Object} context
* @param {Array} args
* @return {null|boolean|number|string|Array|Object}
*/
Function.prototype.callPolyfill = function (context, ...args) {
// 创建一个唯一的 Symbol 属性
const uniqueId = Symbol();
// 将当前函数临时赋值为对象的方法
context[uniqueId] = this;
// 调用函数并传递参数
const result = context[uniqueId](...args);
// 清理临时属性
delete context[uniqueId];
return result;
};
/**
* function increment() { this.count++; return this.count; }
* increment.callPolyfill({count: 1}); // 2
*/