'Is returning "this" in a function a recommended pattern to create objects with methods?
I find myself sometimes needing this pattern in some specific situations but I don't often see it when reading code. I was wondering if this is a recommended pattern or if there's a better/more common way of accomplishing the same thing. Maybe a more modern way to do the same thing in ES6?
Example:
const state = {}
const stubs = {}
const query = () => {
stubs.collection = sinon.stub().callsFake( (collection) => {
state.collection = collection
return this
})
stubs.orderBy = sinon.stub().callsFake( (orderBy, direction) => {
state.orderBy = orderBy
state.direction = direction
return this
})
stubs.limit = sinon.stub().callsFake( (limit) => {
state.limit = limit
return this
})
stubs.get = sinon.stub().callsFake( () => {
const query = state
state = {}
const data = getQuery(query, mockDb)
return data
})
this.collection = stubs.collection
this.orderBy = stubs.orderBy
this.limit = stubs.limit
this.get = stubs.get
return this
}
stubs.firestore = sinon.stub(firebase, 'firestore').get( () => query )
Basically the reason I'm using it in this situation is I had to stub a "query" method for firebase unit tests. It had to work in a chain like this firebase.firestore().collection('users').orderBy('timestamp').limit(10).get(). I messed around with it for like 5 hours and couldn't find another way that worked.
An example without the stubs part would be:
const query = () => {
this.collection = () => {/*something...*/ return this}
this.orderBy = () => {/*something...*/ return this}
this.limit = () => {/*something...*/ return this}
this.get = () => {/*something...*/ return this}
return this
}
I'm not sure why I would actually need to write something like this if I didn't need stubbing, it's just an example to make it more clear what I'm talking about without the stubs part.
Solution 1:[1]
The better way:
const query = () => {
return {
collection() => { /* Code */ }
orderBy() => { /* Code */ }
limit() => { /* Code */ }
get() => { /* Code */ }
}
}
In this way, instead of writing the methods to this and returning this while mutating it (maybe, in a browser, this === window, in non-strict mode), you can directly return an object containing those methods, and the this used inside those method gives the object which is being returned by the query function.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
