Issue
I've found folloing sample in which As if Service class has prototype property.
①Service is not instansiated, why Service = new Service() didn't need ?
②console.log(Service.prototype returned {},what is this object ? What is the merit to manipulate this?
beforeEach(async ()=>{
jest.spyOn(Service.prototype, 'execute')
})
I am totally novice to this concept, if someone has opinion will you please let me know. Thanks
Solution
What this does is that whenever .execute(...) is called on any Service instance, your spying thingy would fire.
It doesn't need new Service() because it's not working on a single service instance, it is working on the class itself.
It works by replacing Service.prototype.execute with a wrapper function that logs the call and then calls the original function, something like this:
const oldExecute = Service.prototype.execute
Service.prototype.execute = function (...args) {
console.log('execute called!', args)
return oldExecute.call(this, ...args)
}
Class methods are nothing other than properties on the class' prototype, so if you have class Test { hello (x) { return x * 2 } } and you do console.log(Test.prototype.hello), it will log the method hello (x) { return x * 2 }, and if you do testInstance.hello(123) it essentially then calls Test.prototype.hello.call(testInstance, 123), i.e. it calls the function Test.prototype.hello with testInstance as this.
And the {} that you see is not everything there is, because the methods are by default non-enumerable. You should look at it in a debugger that also shows non-enumerable properties. Then you will see the class' methods there:
This is also the reason why when referring to the "full name" of a class method, often ClassName.prototype.methodName is used, because that's actually how you would get that method itself without referring to a particular class instance (to make use of it, you would have to call it with its this set to some instance, though, like what I did with .call above). For example, the slice function that exists on Array (when you write [1, 2, 3].slice(1) for instance) is referred to as Array.prototype.slice (in other languages this would be called Array::slice, Array#slice or the like). Sometimes you will also see people talking about Array.slice but that's technically not correct because slice is not a static method and doesn't exists on Array itself (unlike, for example, Array.from).
Further reading:
- MDN: Object prototypes
- MDN: Classes in JavaScript
- MDN: Docs for
Function.prototype.call(to understand the examples) - Jest docs for
spyOn
Answered By - CherryDT

0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.