跳至主要內容

2754. 将函数绑定到上下文 🔒


2754. 将函数绑定到上下文 🔒

🟠   🔗 力扣open in new window LeetCodeopen in new window

题目

Enhance all functions to have the bindPolyfill method. When bindPolyfill is called with a passed object obj, that object becomes the this context for the function.

For example, if you had the code:

function f() {
	console.log('My context is ' + this.ctx);
}
f();

The output would be "My context is undefined". However, if you bound the function:

function f() {
	console.log('My context is ' + this.ctx);
}
const boundFunc = f.boundPolyfill({ ctx: 'My Object' });
boundFunc();

The output should be "My context is My Object".

You may assume that a single non-null object will be passed to the bindPolyfill method.

Please solve it without the built-in Function.bind method.

Example 1:

Input:

fn = function f(multiplier) {
	return this.x * multiplier;
};
obj = { x: 10 };

inputs = [5]

Output: 50

Explanation:

const boundFunc = f.bindPolyfill({ x: 10 });
boundFunc(5); // 50

A multiplier of 5 is passed as a parameter.

The context is set to {"x": 10}.

Multiplying those two numbers yields 50.

Example 2:

Input:

fn = function speak() {
	return 'My name is ' + this.name;
};
obj = { name: 'Kathy' };

inputs = []

Output: "My name is Kathy"

Explanation:

const boundFunc = f.bindPolyfill({ name: 'Kathy' });
boundFunc(); // "My name is Kathy"

Constraints:

  • obj is a non-null object
  • 0 <= inputs.length <= 100

Can you solve it without using any built-in methods?

题目大意

编写一个所有函数都支持的方法 bindPolyfill 。当 bindPolyfill 方法被调用并传递了一个对象 obj 时,该对象将成为函数的 this 上下文。

例如,如果你有以下代码:

function f() {
	console.log('My context is ' + this.ctx);
}
f();

它的输出是 "My context is undefined" 。然而,如果你绑定了该函数:

function f() {
	console.log('My context is ' + this.ctx);
}
const boundFunc = f.boundPolyfill({ ctx: 'My Object' });
boundFunc();

它的输出应为 "My context is My Object"

你可以假设传递给 bindPolyfill 方法的是一个非空对象。

请在不使用内置的 Function.bind 方法的情况下解决该问题。

提示:

  • obj 是一个非空对象
  • 0 <= inputs.length <= 100

你能在不使用任何内置方法的情况下解决这个问题吗?

解题思路

要实现一个 bindPolyfill 方法,需要模仿 JavaScript 中的 Function.prototype.bind 方法的行为。

基本思路是:

  1. 创建一个新的函数,这个函数能够使用传入的对象 obj 作为 this 上下文,该函数也应当支持接受参数。
  2. 当绑定函数时,可能会传入一些参数,这些参数在调用新函数时应该被传递给原函数。因此,需要处理这种情况,确保 bindPolyfill 支持传递参数,类似于 bind 方法那样。
  3. 支持原函数的调用,这意味着新函数在调用时应该调用原函数,并确保 this 指向正确的上下文。

具体来说:

  • bindPolyfill 中,将 this 指向的是被绑定的函数,即调用 boundPolyfill 的函数。例如,如果 f 调用 boundPolyfill,则 this 就是 f
  • 保存原始函数 fn = this,这确保能够在新的函数中调用它。
  • boundPolyfill 返回一个新的函数,这个新函数会把 this 上下文设置为传入的 obj,并将参数 args 传递给原函数 fn,这就确保了原函数能够以正确的上下文和参数调用。

复杂度分析

  • 时间复杂度boundPolyfill 本身的时间复杂度是 O(1),因为它只是创建一个新函数并返回,没有复杂的计算。
  • 空间复杂度O(1),只是为新函数分配了一定的内存。

代码

/**
 * @param {Object} obj
 * @return {Function}
 */
Function.prototype.boundPolyfill = function (obj) {
	// 保存当前函数 (即调用 boundPolyfill 的函数)
	const fn = this;

	// 返回一个新的函数
	return function (...args) {
		// 使用 apply 调用原函数,设置 this 为传入的 obj 并传递 args 参数
		return fn.apply(obj, args);
	};
};