init methods are often used in place of constructors since they are easy to re-call and allow arguments which would not be capable in registered object constructors. In other words, if you make a class in Flash and want to register it to a symbol ID in your library so when you attach that movieclip it will inherit from that object, then you can do so using Object.registerClass. Then, when the movieclip is attached, the constructor of that class will run as it would for any object created from that class. The problem is you cant pass arguments to that constructor function since its (more or less) called from attachMovie. You can use an init object, but those arent arguments for the constructor, they are actually copied into the movieclip object before the constructor call. In that respect they are available to the constructor but they are automatically in the movieclip object and not really usable as normal constructor arguments. This is where init comes into play
An init method is basically your constructor method but not the constructor. Everything your constructor would have done is then done through the init method. This way you can attach your movieclip and then call init with whatever arguments you want as if calling the constructor with actual arguments - something not possible normally with the attachMovie and a registered class. i.e.:
ball = function(){}
ball.prototype.init = function(speed, mass){
this.speed = speed;
this.mass = mass;
}
Object.registerClass("BallLibraryID",ball);
this.attachMovie("BallLibraryID","myBall",1);
myBall.init(10, 5);
trace(myBall.speed); // 10
trace(myBall.mass); // 5
Since the init method is also a method of the object, it can be called anytime for that object which can practically re-instate the constructor (since your constructor junk would then be in your init method) without creating a new object alltogether, which recalling the class function (the real constructor) would do. i.e.:
// reset ball speed and mass (reconstruct)
myBall.init(2, 1);
trace(myBall.speed); // 2
trace(myBall.mass); // 1
Now, the apply method is a function method which lets you specify an object and an array of parameters to be applied to that function in the object as the arguments array. wheew. So you have a function, you use apply on that and pass in 1) and object and 2) an arguments array i.e.
myFunction.apply(myObject, [a,b,c,moreArguments]);
which resolves to
myObject.myFunction(a,b,c,moreArguments);
This is a great function for, not only calling methods which dont exist in objects for those objects, but also as a way to translate an array of values into arguments for any function.
Now, one could write a single init method for all classes using apply because of that first part mentioned above - the ability to call a function on an object which doesnt ‘have’ that function, or that function isnt a method of that object. There would have to be a little trickery involved though to determine propname vs value, but nothing unpossible i.e.:
guy = function(){};
girl = function(){};
_global.init = function(){
for (var i=0;i<arguments.length;i+=2) this[arguments*] = arguments[i+1];
}
bob = new guy();
init.apply(bob, ["arms",2,"heads",1]);
trace(bob.arms); // 2
trace(bob.heads); // 1
jen = new girl();
init.apply(jen, ["fingers",10,"piercings",20]);
trace(jen.fingers); // 10
trace(jen.piercings); // 20
here, every other array element in the arguments array is either a property name or the value so arms, as you see will be 2 and fingers, 10 etc…
Otherwise, seperate inits are made for each class (a prototype) which are to be run for each - apply can then be used just for the convenience of passing an array which maybe, considering the circumstances, adventageous. For instance, just keeping an array to specify the init arguments and updating any one of its values at anytime when needed. Then when you need to apply them to the object do so with apply
init.apply(myObject, myObject.initArgsArray)
I personally always use a seperate init (as do most people - yeah ok, no one probably uses the above method ;)) because not all constructors are simple assignment and can involve conditions or seperate ways to handle the passed arguments based on their value or the value of other conditions etc.
An alternative, and what he means most likely, is using apply to call the init from the constructor if any arguments are passed to that constructor, preventing you to have to call init seperately. Init would still be needed for attachMovie. i.e.
ball = function(){
if (arguments.length) this.init.apply(this, arguments);
};
ball.prototype.init = function(speed, mass){
this.speed = speed;
this.mass = mass;
}
myBall = new ball(10, 5); // init automatically called
// if ball were a movieclip class, init would need
// run the constructor since no arguments were
// passed from attachMovie calling the constructor
Object.registerClass("ball_id", ball);
this.attachMovie("ball_id", myBall, 1).init(10, 5);
Then all constructors can be written that way and redirect directly to their init method.
:beam: