当涉及到使用 .bind() 的函数柯里化时,this 变量的作用是什么?

What is the role of the this variable when it comes to function currying using the .bind()?

我遇到了以下 JS 代码 (ES5) 我真的不明白 this 变量的含义。

function multiply(a,b){
  return a * b;
}

var multipleByThree = multiply.bind(this,3);

multipleByThree(10) // outputs 30

我知道 bind 复制乘法函数,它的 'a' 参数的值为 3。但是这个变量的目的是什么?

你能帮帮我吗?

它固定3为第一个参数,新函数的参数将以3开头

function multiply(a,b){
  console.log(a, b);
  console.log(arguments)
  return a * b;
}

var multipleByThree = multiply.bind(console.log(this),3);

console.log(multipleByThree(10)) // outputs 30
console.log(multipleByThree(10, 15)) // outputs 30

传递 this 将提供 this(即全局对象)的副本以及前面的参数列表

有关详细信息,请查看 MDN docs

您提供给 .bind()this 变量是上下文。在您的情况下,this 指的是全局对象 space.

这是一个如何工作的例子:

var message = 'within global context';
function multiply(a,b){
  console.log(this.message);
  return a * b;
}

var someOtherContext = {
  message: 'within some other context'
};

var multipleByThree = multiply.bind(this,3);
var multipleByThreeOtherContext = multiply.bind(someOtherContext, 3);

console.log(multipleByThree(10))
console.log(multipleByThreeOtherContext(10))

通过改变 multiply 在其中执行的上下文,我们可以改变它引用的变量。

bind 的第一个参数必须是 thisArg:

fun.bind(thisArg[, arg1[, arg2[, ...]]])

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind

也就是关键字this里面multiply会引用什么。由于 multiply 根本不使用 this,因此它所指的内容无关紧要。您仍然必须将 something 作为第一个参数传递给 bind,因此开发人员可能只是选择了 this(我们不知道这段代码中指的是什么) , 但他们也可以使用 falsenull 或其他任何东西。

在javascript中this是某种"reserved keyword",它指的是作用域的当前对象。

如果 this 在任何对象之外使用 - 它指的是 window 对象。
内部事件处理程序 this 指的是引发事件的 DOM 对象。

bind 函数提供了定义哪个对象 this 将引用内部绑定函数的可能性。

例如,如果您在函数

中使用 this
const calculate = function (price, amount) {
    return (price * amount) - this.discount;
};

您可以使用预定义的函数绑定 this

const calculateWithDiscount = calculate.bind({ discount: 100 });

const total = calculateWithDiscount(1000, 2); // return 1900

当您绑定不使用 this 对象的函数时,您可以轻松地将 null 传递到那里,这清楚 "tell" 其他开发人员您使用 this 的意图在函数中。

const add = function (a, b) {
    return a + b;
};
const add5 = add.bind(null, 5);

const result = add5(19); // return 24

bind Method (Function) (JavaScript)

就其价值而言,您可以在不依赖 Function.prototype.bind

的情况下进行柯里化

一旦您不再依赖 JavaScript 中的 this,您的程序就会开始看起来像漂亮的表达式

const curry = f => x => y =>
  f (x,y)
  
const mult = (x,y) =>
  x * y

const multByThree =
  curry (mult) (3)
  
console.log (multByThree (10)) // 30


对于更通用的curry实现,适用于不同数量的函数

const curry = (f, n = f.length, xs = []) =>
  n === 0
    ? f (...xs)
    : x => curry (f, n - 1, xs.concat ([x]))

如果您想对公开的私有 API 感到痛心,请用循环将其隐藏起来 – 无论哪种方式,this 都不需要在 JavaScript[= 中编写函数式程序17=]

const loop = f =>
  {
    const recur = (...values) =>
      f (recur, ...values)
    return f (recur)
  }

const curry = f =>
  loop ((recur, n = f.length, xs = []) =>
    n === 0
      ? f (...xs)
      : x => recur (n - 1, xs.concat ([x])))

在 Currying 的上下文中,所提供代码中的 this 对象除了用作 占位符 外没有其他用途。如果需要,您可以将其替换为字符串 "cats" 并且仍然会得到相同的结果。它只是在那里占据第一个参数位置,我认为在上下文中使用它是非常误导的 使用绑定时,柯里化或部分应用。最好换成null关键字。

在此示例中,它将传入全局对象,其余代码将简单地忽略该值,因为关键字 'this' 不存在 within 乘法函数本身。

MDN展示了一个用例,访问https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind 并滚动到部分应用函数部分。

ES6(aka es2015)改进了使用箭头函数编写此代码的方式,现在代码可以简化为以下内容

const multiply = a => b => a * b

const multiplyByThree = multiply(3)

const result = multiplyByThree(10)
console.log(result)
// => 30