Explanation of update() function in OrbitControls

javascript

#1

Hi,

Can someone explain how the implementation of the function update() in OrbitControls.js works?

Within OrbitControls.js (in here) I see a outer “update” function that calls a inner “update” function.
See the following code:

// this method is exposed, but perhaps it would be better if we can make it private…
this.update = function () {
console.log(‘In outer function update’);

var offset = new THREE.Vector3();

return function update() {

          console.log('In inner function update');
  var position = scope.object.position;
          ...

I placed printouts inside both update functions.
When running the code, I’m getting into the outer function once, when instantiating a new OrbitControls object (this is because of the parentheses at the end of the function definition)
After that all the calls to update() within OrbitControls (e.g. the function “reset()”) invoke the inner function “update”

Why is that?
Why does calling “scope.update()” from within the function “reset” invokes the inner “update” function and not the “outer”?

Thanks,
Avner


#2

I don’t know the answer as I haven’t had the need to search that deep into OrbitalControls, but are you are indicating you may be running into a problem because of it? or is it out of curiosity you want to understand it.


#3

It is more a javascript understanding question.
I’m trying to understand some of the internal calculations because something is not working for me :confused:
I don’t think there is a problem with the code.


#4

I see, If you feel like it, you can try to give a simplified example of your scenario, i’m sure someone on here could maybe give you a solution or point you closer to a solution.

For example, when I started using the OrbitalControls, I thought there was something wrong with the controls when rotating from different angles, but later realized the issue was more related to my scene orientation setup and not the OrbitalControls.


#5

What you see is a design pattern in JavaScript and used to create additional scopes for variables. This scope is called “closure scope”. To be more precise:

this.update = function () {

    var offset = new THREE.Vector3(); // closure scope variable

    return function update() {

        // use offset right here

    };

}();

In this scenario, offset is just created once and then reused. At the same time, it is no global variable but only visible in the update() function. Object creation is an expensive operation in JavaScript, so it’s beneficial for performance-critical code to avoid it as much as possible. You see the usage of such closures at different places in the source code of three.js. When developing with classes, such variables are usually placed in the corresponding module. In this case, they are module scope variables. If you google “JavaScript Closure”, you will find many articles and blog post about that topic.


#6

Thanks. Your explanation is helpful.