I'm trying to call a method from a require
d Node module with a specific this
object. As far as I see, there are three ways to do this, with .bind(obj)(args)
, or with .call(obj, arg1, ...)
, or with .apply(obj, aryArgs)
. I'm currently using bind
, but I have tried all three with identical levels of not-success.
This is where I'm running the call:
var library = require("./library.js");
// ...
requestHandler.bind(library)(req);
requestHandler
is a reference to the exported status
function from this file:
exports.status = () => {
console.log(this);
this.render({text: "status ok"});
};
exports.paramSwitching = () => {
this.render("rendered via param switching");
};
exports.json = () => {
this.render({json: {this: 'renders', as: 'json'}});
};
exports.view = () => {
this.render({view: true, locals: {text: 'hi'}});
};
I'd like this to work so that the status
function is called with library
as its this
object, since that's where render
is defined. However, the console.log
statement is showing this
as the evaluated contents of the file holding status
, ie
{ status: [Function],
paramSwitching: [Function],
json: [Function],
view: [Function] }
What's happening here, and how do I fix it? (Or, if I can't because Node is doing something weird, is there a workaround?)
The arrow function itself already binds the this
within the function body function to the this
of the context it was defined in. So you cannot change the this
with any of those methods.
If you need to change the this
then you cannot use arrow functions.
Your request handler is declared with arrow notation:
exports.status = () => {
console.log(this);
this.render({text: "status ok"});
};
By design the arrow notation captures this
at the time the function is declared. It is almost as if you did this:
exports.status = (function(){
console.log(this);
this.render({text: "status ok"});
}).bind(this);
This means the status()
function is already bound and cannot be rebound. The solution is to stop using arrow functions:
exports.status = function(){
console.log(this);
this.render({text: "status ok"});
};
Figured it out right after I posted this question. I've used arrow functions in the file containing status
, which do not create their own this
scope but use the enclosing context.
Calling bind
, call
or apply
on these functions has no effect because this
is already set to the function's enclosing context, which in this case is the eval'd file.
Switching the arrow functions out for regular functions (changing () =>
to function ()
) has fixed the issue.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.