简体   繁体   English

当使用.bind()进行函数调用时,此变量的作用是什么?

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

I came across to the following JS code (ES5) and I don't really I understand what is the meaning of the this variable. 我遇到了以下JS代码(ES5),但我真的不明白此变量的含义是什么。

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

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

multipleByThree(10) // outputs 30

I do understand that the bind copies the multiply function and that 'a' parameter of it, will have the value 3. But what is the purpose of the this variable? 我确实知道绑定会复制乘法函数,并且它的“ a”参数将具有值3。但是此变量的目的是什么?

Can you help me out please? 你能帮我吗?

The this variable that you are providing to .bind() is the context. 您要提供给.bind()this变量是上下文。 In your case, this refers to the global object space. 在您的情况下, this是指全局对象空间。

Here's an example of how this works: 这是一个如何工作的示例:

 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)) 

By changing the context that multiply executed within, we can change what variables it references. 通过更改在其中执行乘法的上下文,我们可以更改其引用的变量。

The first argument to bind must be the thisArg : bind的第一个参数必须是thisArg

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

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

That is, whatever the keyword this inside multiply will refer to. 也就是说,无论this 内部 multiply的关键字是什么。 Since multiply doesn't use this at all, it's irrelevant what it refers to. 由于multiply不使用this的话,那是无关紧要的东西它是指。 You must still pass something as the first argument to bind , so likely the developer simply chose this (whatever that refers to in this code is unknown to us), but they could just as well have used false , null or anything else. 您仍然必须传递某些内容作为bind的第一个参数,因此很可能开发人员只是选择了this (此代码中所指的内容对我们来说是未知的),但他们也可以使用falsenull或其他任何内容。

In javascript this is some kind of "reserved keyword" which refers to current object of the scope. 在javascript中, this是某种“保留关键字”,它表示范围的当前对象。

If this used outside of any object - it refers to window object. 如果在任何对象之外使用this对象,则表示window对象。
Inside eventhandlers this refers to the DOM object which raised an event. 在事件处理程序内部, this是指引发事件的DOM对象。

bind function provide possibility to define which object this will refer inside bound function. bind函数提供可能性来定义哪个对象this将是指内部约束功能。

For example if you using this inside function 例如,如果您使用this内部函数

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

You can bound a function with predefined this 您可以绑定功能与预定义的this

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

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

When you bound function which doesn't use this object, you can easily pass null there, which clearly "tell" other developers your intents about using this in the function. 当你势必不使用功能this对象,你可以很容易地通过null在那里,它清楚地“告诉”其他开发商的意图有关使用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) 绑定方法(函数)(JavaScript)

For what it's worth, you can do currying without relying upon Function.prototype.bind 对于它的价值,您可以不依赖Function.prototype.bind进行循环

Once you stop relying upon this in JavaScript, your programs can start looking like beautiful expressions 一旦你停止依赖于this在JavaScript中,你的程序就可以开始寻找喜欢漂亮的表情

 const curry = f => x => y => f (x,y) const mult = (x,y) => x * y const multByThree = curry (mult) (3) console.log (multByThree (10)) // 30 


For a more generic curry implementation that works on functions of varying arity 对于更通用的curry实现,可以实现各种功能

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

If you want to bellyache about the exposed private API, hide it away with a loop – either way, this is not required to write functional programs in JavaScript 如果你想腹痛关于暴露私有API,具有循环隐藏了-无论哪种方式, this并不需要JavaScript编写的功能程序

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])))

it fixes 3 as the first argument, the arguments of the new function will be preceded by 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 

passing this would provide a copy of this(ie the global object) with the preceded arguments list 传递此参数将提供此参数(即全局对象)的副本以及前面的参数列表

For more information check out the MDN docs 有关更多信息,请查看MDN文档

In the context of Currying the this object in the code presented has no purpose other than as a placeholder . 在Currying上下文中,所提供代码中的此对象除用作占位符外没有其他目的。 You could replace this with the string "cats" if you wanted and still get the same result. 如果需要,可以将其替换为字符串“ cats”,并且仍然获得相同的结果。 It is simply there to occupy the first argument position and I think it is very misleading to use it in the context of either currying or partial application when using bind. 它只是在这里占据第一个参数位置,我认为在使用bind时在临时应用程序或部分应用程序的上下文中使用它会产生很大的误导。 It is better to replace it with the null keyword. 最好用null关键字替换它。

In the case of this example it will pass in the global object and the rest of the code will simply ignore that value since the keyword 'this' is not present within the multiply function itself. 在这个例子的情况下它会通过在全局对象和代码的其余部分将简单地忽略由于关键字“这个”不是乘法函数本身存在该值。

MDN shows a use case, visit https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind and scroll to the section headed Partially applied functions. MDN显示了一个用例,请访问https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind并滚动至部分应用的功能部分。

ES6 (aka es2015) has improved on the way this code is written by using arrow functions and the code can now be reduced to the following ES6(aka es2015)通过使用箭头功能改进了编写此代码的方式,现在可以将代码简化为以下内容

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

const multiplyByThree = multiply(3)

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM