2

whats the advantage of a function definition like this: obj = { func: function(){return function func(){return this.something;};}() }

Story: I was looking for a way how to rotate a Three.js Vector3 by a certain angle around an axis and found this: How to rotate a Three.js Vector3 around an axis? I was interested in how the function works and looked it up: https://github.com/mrdoob/three.js/blob/master/src/math/Vector3.js. The function looks like this:

applyAxisAngle: function () {

    var quaternion;

    return function applyAxisAngle( axis, angle ) {

        if ( quaternion === undefined ) quaternion = new Quaternion();

        return this.applyQuaternion( quaternion.setFromAxisAngle( axis, angle ) );

    };

}(),

So whats the reason for this way of the defining a function?

Community
  • 1
  • 1
jl005
  • 110
  • 3
  • 8

2 Answers2

2

The immediately-invoked function expression (IIFE) lets the author of that code give the applyAxisAngle function a truly private quaternion variable that nothing else anywhere can see.

That code basically does this:

var quaternion;

// ...

applyAxisAngle: function applyAxisAngle( axis, angle ) {

    if ( quaternion === undefined ) quaternion = new Quaternion();

    return this.applyQuaternion( quaternion.setFromAxisAngle( axis, angle ) );
},

...but keeping quaternion entirely private, rather than sharing it with code in the scope where all of this appears.

It defers constructing the Quaternion object until the first time it's called, and then it reuses that object in all subsequent calls by using the value from that private quaternion variable.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
2

Actually, the reason applyAxisAngle() was written that way was not to keep quaternion private, although that is, in fact, a side effect of the implementation.

It was written that way to avoid instantiating a new Quaternion() every time the method is called, and consequently, avoiding garbage collection.

applyAxisAngle() is often called in tight loops -- many times a second. Writing the method this way, the Quaternion is instantiated only once.

The implemented construct is called a "closure".

WestLangley
  • 102,557
  • 10
  • 276
  • 276