2693. 使用自定义上下文调用函数
增强所有函数,使其具有 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) { return this.a + b; } args = [{"a": 5}, 7] 输出:12 解释: fn.callPolyfill({"a": 5}, 7); // 12callPolyfill
将 "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 <= 105
原站题解
javascript 解法, 执行用时: 68 ms, 内存消耗: 40.8 MB, 提交时间: 2023-05-22 14:22:20
/** * @param {Object} context * @param {any[]} args * @return {any} */ Function.prototype.callPolyfill = function(context, ...args) { var context = context || window Reflect.defineProperty(context, 'fn' , { enumerable: false, writable:false, value:this }) return context['fn'](...args) } /** * function increment() { this.count++; return this.count; } * increment.callPolyfill({count: 1}); // 2 */
javascript 解法, 执行用时: 68 ms, 内存消耗: 40.9 MB, 提交时间: 2023-05-22 14:21:56
/** * @param {Object} context * @param {any[]} args * @return {any} */ Function.prototype.callPolyfill = function(context, ...args) { return this.apply(context, args); } /** * function increment() { this.count++; return this.count; } * increment.callPolyfill({count: 1}); // 2 */
typescript 解法, 执行用时: 72 ms, 内存消耗: 42.5 MB, 提交时间: 2023-05-22 14:21:03
declare global { interface Function { callPolyfill(context: Record<any, any>, ...args: any[]): any } } Function.prototype.callPolyfill = function(context, ...args): any { return this.apply(context, [...args]) } /** * function increment() { this.count++; return this.count; } * increment.callPolyfill({count: 1}); // 2 */
javascript 解法, 执行用时: 76 ms, 内存消耗: 43 MB, 提交时间: 2023-05-22 14:20:27
/** * @param {Object} context * @param {any[]} args * @return {any} */ Function.prototype.callPolyfill = function (context, ...args) { const name = this.name const fn = this; const proxy = new Proxy(context, { get(target, prop) { if (prop === name) { return fn } return Reflect.get(...arguments) } }) return proxy[name](...args) } /** * function increment() { this.count++; return this.count; } * increment.callPolyfill({count: 1}); // 2 */
typescript 解法, 执行用时: 96 ms, 内存消耗: 42.7 MB, 提交时间: 2023-05-22 14:19:52
declare global { interface Function { callPolyfill(context: Record<any, any>, ...args: any[]): any; } } Function.prototype.callPolyfill = function(this: Function, context: Record<PropertyKey, any>, ...args: any[]): any { const sym = Symbol(); context[sym] = this; //这里的this为调用call的函数本身 const res = context[sym](...args); delete context[sym]; return res; } /** * function increment() { this.count++; return this.count; } * increment.callPolyfill({count: 1}); // 2 */