I am hoping to clear up some of my confusion pertaining to arrow functions and lexical this, my use case with mongoose.
When adding a method to a mongoose Schema, one cannot use an arrow function. According to this article: https://hackernoon.com/javascript-es6-arrow-functions-and-lexical-this-f2a3e2a5e8c4 "Lexical Scoping just means that it uses this from the code that contains the Arrow Function."
So if I use an arrow function in a mongoose method, why does 'this' not refer to the schema object, whereas a pre-es6 function does? If the schema and arrow function are in the same file, is the lexical scope not bound to the schema?
Thank you!
UserSchema.methods.toJSON = function() {
const user = this;
const userObject = user.toObject();
return _.pick(userObject, ['_id', 'email']);
};
Lexical Scoping just means that it uses this from the code that contains the Arrow Function.
I'll just demonstrate it:
window.answer = 'Unknown'; // `this` equals to `window` in browser (no strict mode)
const object = {
answer: 42,
arrow: () => this.answer,
wrap() {
const arrow = () => this.answer;
return arrow();
},
stillOuter() { return this.arrow();},
method() {return this.answer;},
likeArrow: function() {return this.answer;}.bind(this)
};
console.log(object.arrow(), object.stillOuter(), object.likeArrow()); // Unknown Unknown
console.log(object.method(), object.wrap()); // 42 42
Arrow function's this
just belongs to outer context.
So, if your arrow functions will be declared inside of correct object, this
will be correct(almost) too.
Look into that workaround:
let tmp = Symbol(); // just to not interfere with something
UserSchema.methods[tmp] = function() {
this.toJson = data => JSON.stringify(data);
// All arrow functions here point into `UserSchema.methods` object
// It will be still `UserSchema.methods` if implementation will copy these methods into other objects or call in the other context
};
UserSchema.methods[tmp]();
delete UserSchema.methods[tmp];
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With