The object has a method written to the prototype:

ServisePlate.prototype.disclose = function() { console.log('запустилась функция disclose'); function showBody() { if(this.elem.offsetHeight < (this.body.offsetHeight + this.initialSize)) { this.elem.style.height = this.elem.offsetHeight + this.settings.step + 'px'; setTimeout(showBody.call(this), this.settings.speed); } } function hideBody() { if(this.elem.offsetHeight > this.initialSize) { this.elem.style.height = this.elem.offsetHeight - this.settings.step + 'px'; setTimeout(hideBody.call(this), this.settings.speed); }else { this.elem.style.height = ''; } } if(this.elem.offsetHeight == this.initialSize || this.elem.offsetHeight >= (this.body.offsetHeight + this.initialSize)) { if(this.elem.offsetHeight == this.initialSize) { console.log('Сработало условие 1'); showBody.call(this); } else { console.log('Сработало условие 2') hideBody.call(this); } } } 

It has two internal functions, hideBody and showBody .
How to attach object context to them? Via call(this) , as in the code above, all functions are started and executed except for the variables declared in the constructor - this is an object:

 this.settings = { step: 30, speed: 1000 } 

its properties define the pixel increment step and the restart timeout. So I work the functions as if they are not there ..... although from these functions their values ​​are derived via console.log .
In theory, with such values ​​every second 30px should be added to the height property, but the desired height is obtained instantly, without smooth addition.
Through apply everything happens exactly the same, and functions do not run at all through bind .
How to be?

  • why these functions are simply not placed in the prototype? Why invent yourself difficulties? :-) - Grundy
  • @Grundy, do you mean the prototype of the object itself? Xs, you can of course in the prototype, but I thought it would be more correct if they are internal functions of the method .... so to speak, its implementation ... After all, except for this method, they are not needed by anyone. - pepel_xD

1 answer 1

There is a misuse of technology.

The simplest solution: to transfer these functions to the prototype of the object - there is no need to change the context, there are no problems with incorrect use of call .

Specifically, in this code, the problem is that setTimeout , the first parameter, expects a function . The use of the same call calls the function immediately.

That is, in this case it was necessary to use bind

Another option to avoid problems with changing the context, use the arrow functions

For example:

 var showBody = ()=>{ ... setTimeout(showBody, this.settings.speed) } 
  • Another question: Does it make sense to delete the timeout after the function has finished? - pepel_xD
  • @pepel_xD, no, if the function has already been executed, a call on the clearTimeout timer will give nothing - Grundy