如何在函数定义中使用没有 "this" 的 bind() 方法?
How do you use the bind() method without "this" within the function definition?
我已经阅读了很多关于方法 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
在他们的函数定义中。 bind() 的第一个参数不是您希望预先存在的 this
指向的地方吗?
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();
请注意,newcheckthis
是 checkthis
函数,但 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...);
Isn't the first argument of bind() where you want the pre-existing this to point towards?
是的,完全正确。
In this example, eventLoader.load.bind(this, user._doc.createdEvents)
uses this
as an argument for bind()
even though the eventLoader
function nor the events
function have this
in their function definition.
更准确地说,DataLoader.load 需要 this
作为 DataLoader 才能正常工作。因此 .bind
事件加载器 eventLoader.bind(eventLoader, ...)
.¹
是有意义的
绑定 this
没有意义,因为那是 window
(因为箭头函数采用父函数 ² 的上下文,并且因为您没有父函数 [从显示的代码中]父级是全局范围)。
¹ Read on
我已经阅读了很多关于方法 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
在他们的函数定义中。 bind() 的第一个参数不是您希望预先存在的 this
指向的地方吗?
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();
请注意,newcheckthis
是 checkthis
函数,但 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...);
Isn't the first argument of bind() where you want the pre-existing this to point towards?
是的,完全正确。
In this example,
eventLoader.load.bind(this, user._doc.createdEvents)
usesthis
as an argument forbind()
even though theeventLoader
function nor theevents
function havethis
in their function definition.
更准确地说,DataLoader.load 需要 this
作为 DataLoader 才能正常工作。因此 .bind
事件加载器 eventLoader.bind(eventLoader, ...)
.¹
绑定 this
没有意义,因为那是 window
(因为箭头函数采用父函数 ² 的上下文,并且因为您没有父函数 [从显示的代码中]父级是全局范围)。
¹ Read on