如何在函数定义中使用不带“ this”的bind()方法?

时间:2019-04-28 19:30:47

标签: javascript function this bind

我已经阅读了很多关于方法bind()的知识,并且我开始理解它将this设置为特定对象。这几乎总是意味着函数定义内的某个地方指向特定对象的this。但是,我看到在函数的定义中使用bind()而不使用this的情况。更具体地说,this被用作参数,这使我感到困惑。例如,

const eventLoader = new DataLoader((eventIds) => {
  return events(eventIds);
});

const events = async eventIds => {
  try {
    const events = await Event.find({ _id: { $in: eventIds } });
    return events.map(event => {
      return transformEvent(event);
    });
  } catch (err) {
    throw err;
  }
};

const user = async userId => {
  try {
    const user = await userLoader.load(userId.toString());
    return {
      ...user._doc,
      _id: user.id,
      createdEvents: eventLoader.load.bind(this, user._doc.createdEvents)
    };
  } catch (err) {
    throw err;
  }
};

在此示例中,即使eventLoader.load.bind(this, user._doc.createdEvents)函数和this函数具有bind()eventLoader仍使用events作为this的参数。在其功能定义中。您想让先前存在的this指向bind()的第一个参数吗?

2 个答案:

答案 0 :(得分:2)

  

bind()的第一个参数不是您想要预先存在的参数指向的位置吗?

是的。

  

在此示例中,即使eventLoader.load.bind(this, user._doc.createdEvents)函数和this函数具有bind()eventLoader仍使用events作为this的参数。在其功能定义中。

更准确地说,DataLoader.load需要this作为DataLoader才能正常工作。因此,将.bind的eventLoader eventLoader.bind(eventLoader, ...)设置为有意义。¹

绑定this没有意义,因为绑定window(因为箭头函数采用父函数²的上下文,并且由于没有父函数[根据显示的代码],所以父是全球范围)。

¹Read on

²Even more to read

答案 1 :(得分:0)

在调用函数时,bind函数的第一个参数设置this的值。

示例:

// You have an object
var obj = { test: "Yeah, test!" };
// We check the object properties
console.log(obj.test);

// We define a function to work with an argument
function check(myobj) {
    console.log("Is the same object?", obj === myobj);
    console.log("Is the same object?", myobj.test);
}

// Now we define a function that will work with an object as "this"
function checkthis() {
    // Notice how I use the "this" keyword, which will be the one that inherits or the one that you set
    console.log("Is the same object?", obj === this);
    console.log("Is the same object?", this.test);
}

// We call the first check
check(obj);

// Now we call the second checkthis but with another "this" context
// The first argument of call() will set the "this" context of the function and then call it instantly.
checkthis.call(obj);

// And now we are going to save another function with the this context changed.
// The first argument of bind() will also set the "this" context, but will save a reference of the function for later use, instead of calling it.
var newcheckthis = checkthis.bind(obj);

// Now we call this new function.
newcheckthis();

请注意,newcheckthischeckthis函数,但this上下文已更改。 checkthis将保留其上下文。

此外,您可以使用bind强制使用this创建函数引用。上下文已更改,并设置了默认参数。

示例:

// We create a function that will sum the some this object value to an argument
function sum(sumvalue) {
    return this.value + sumvalue;
}

// We create the main object
var obj = { value: 10 };

// Then we call the function setting the "this" context and passing an argument
// Note how I pass obj as the first argument and 5 as the second
// Actually it will set as the first argument (sumvalue) the second argument in the call, as the first argument in the call will be set to the "this" context. 
var result = sum.call(obj, 5);

// And we can use the same trick with bind()
var newsum = sum.bind(obj, 5);

// Now we have a newsum  function that has the this context set to "obj" and the first argument (sumvalue) set to 5 by default, which cannot be replaced.
// If we cann the function, it will di the same as the call() function above
result = newsum();

// result will still be 15.

因此,call()bind()(还有另一个:apply(),但工作原理有所不同)将具有以下签名:

.bind/.call(THISCONTEXT, THIS_2ND_ARGUMENT_WILL_BE_THE_FIRST_ONE, 3RD_AS_SECOND, AND_SO_ON...);