列表

详情


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); // 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 作为附加参数传递。

 

提示:

原站题解

去查看

上次编辑到这里,代码来自缓存 点击恢复默认模板
/** * @param {Object} context * @param {any[]} args * @return {any} */ Function.prototype.callPolyfill = function(context, ...args) { } /** * function increment() { this.count++; return this.count; } * increment.callPolyfill({count: 1}); // 2 */

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
 */

上一题