Best way to define "private" functions

B

blackholebutterfly

I have seen a couple of ways to define private functions inside other
functions.

1.
var myFunc1 = function() {

function myInnerFunc() {
}
};

2.
var myFunc2 = function() {

var myInnerFunc = function () {
};
};

Let's assume that both myFunc1 and myFunc2 have a "public" method also
that calls the "private" method:
this.init = function() {
myInnerFunc
};

Is there any reason to write/define the private methods one way as
opposed to the other? I am leaning toward using the 2nd way (using var
myInnerFunc = ...) but I cannot give a good reason for choosing this
way instead of the way in #1 above. (I realize that the -- this --
keyword is unavailable in the private method using either construct.)

As always, many thanks.
b l a c k h o l e b u t t e r f l y
 
D

dhtml

I have seen a couple of ways to define private functions inside other
functions.

1.
var myFunc1 = function() {

function myInnerFunc() {
}

};

2.
var myFunc2 = function() {

var myInnerFunc = function () {
};

};

Let's assume that both myFunc1 and myFunc2 have a "public" method also
that calls the "private" method:
this.init = function() {
myInnerFunc

};

Is there any reason to write/define the private methods one way as
opposed to the other? I am leaning toward using the 2nd way (using var
myInnerFunc = ...) but I cannot give a good reason for choosing this
way instead of the way in #1 above. (I realize that the -- this --
keyword is unavailable in the private method using either construct.)

I usually prefer function declarations over function exp. Function
declarations are parsed first so you can refer to them -- even call
them before they appear.

function Master() {

this.init = pub;

function pub() {
var r = Math.random();
if( r > .1 )
randInt(r);
};

function randInt(r) {
document.title = r * 10 | 0;
}
}

The reason I prefer this way is that you see what the object is all
about right at the very top. I use a closure in a similar manner for
an exporting pattern - export at the top, function declarations below.
I don't program in Perl, but it is similar to this pattern:
http://perldesignpatterns.com/?ExportingPattern

except in JavaScript.

The other benefit to function declarations are that they have an
identifier. With function expression, the identifier is optional and
jscript ends up treating it like a function declaration anyway (it's a
bug).

I used the approach here:
http://dhtmlkitchen.com/ape/build/dom/viewport-f.
http://dhtmlkitchen.com/ape/build/dom/classname-f.js

Garrett
 
D

dhtml

On Feb 27, 10:36 pm, (e-mail address removed) wrote:
The other benefit to function declarations are that they have an
identifier. With function expression, the identifier is optional and
jscript ends up treating it like a function declaration anyway (it's a
bug).

I should qualify that:
JScript interprets a function expression with an identifier as a
function expression and a function declaration -- the identifier
affects the enclosing scope.
 
B

blackholebutterfly

I should qualify that:
JScript interprets a function expression with an identifier as a
function expression and a function declaration -- the identifier
affects the enclosing scope.

Are there any advantages to using function expressions in this
situation? I feel like I see them all the time in code, but have never
stopped to wonder why they might be used.
 
D

dhtml

Are there any advantages to using function expressions in this
situation? I feel like I see them all the time in code, but have never
stopped to wonder why they might be used.

FunctionExpressions can be used in blocks.

This makes it possible to:

var f;
if(typeof document.documentElement.clientTop == "number") {
f = function(el) {
// using clientTop
};
} else if(document.defaultView &&
document.defaultView.getComputedStyle) {
f = function(el) {
// using computedStyle
};
}
 
B

blackholebutterfly

FunctionExpressions can be used in blocks.

So apart from blocks, in the situation where you have a simple "class"
of public and private methods, isn't it true to say that using
function declarations (for private) is less prone to error, since the
priv. function can be called from anywhere in the class, even before
the declaration whereas calling a func. created through assignments is
dependent on the assignment having previously taken place?
 
D

dhtml

So apart from blocks, in the situation where you have a simple "class"
of public and private methods, isn't it true to say that using
function declarations (for private) is less prone to error, since the
priv. function can be called from anywhere in the class, even before
the declaration whereas calling a func. created through assignments is
dependent on the assignment having previously taken place?

A function declaration does allow the function to be moved around in
source order, that is true. The errors that might be avoided -
Reference Error - would be easy to spot even with a function
expression.

function C(){
this.f = priv; // reference error.
var priv = function() { }
}

So this isn't a strong argument for choosing function declaration over
function expression.

Stylistically, I don't like having init routines in a constructor.

This could be accomplished with the module pattern, but would require
moving the object's public interface to the bottom. I find this
undesirable:

var x = (function() {

return { m : m }; // 2nd pass - Statement processed, return

// first pass, c is added to variable object with value "undefined".
var c = 23;

// first pass, m is added to the variable object as a function.
function m() {
document.title = "Aika " + c;
}
})();

x.m();

The result would be title = "Aika undefined". To fix this, you could
move the return statement to the bottom (which feels like the right
place for a return statement) --


var x = (function() {

// first pass, c is added to variable object with value "undefined".
var c = 22;

// first pass, m is added to the variable object as a function.
function m() {
document.title = "Aika " + c;
}

return { m : m }; // 2nd pass - Statement processed, return
})();

x.m();

--
But now the returned object - the one that gets assigned to x - is
described all the way at the bottom. Objects get bigger. If the return
statement is all the way at the bottom, it requires scrolling through
possibly 500+ lines just to find out what the object is about. I
prefer to see what it's about right away. It's clearer to have the
export right at the very top, so you see what the object is about
first:

var x;
(function() { // function expression

x = { m : m };

var c = 24;

function m() {
// "private" method.
function m_priv() { document.title = "Aika: " + c; }

// now assign private method as property of this.
this.m = m_priv;
return this.m();
}
})();

x.m();


Garrett
 
D

dhtml

A function declaration does allow the function to be moved around in
source order, that is true. The errors that might be avoided -
Reference Error - would be easy to spot even with a function
expression.

function C(){
this.f = priv; // reference error.
var priv = function() { }

}

Actually, sorry, it's a reference error only when this.f is called.

that is because this.f points to priv, and when the C function is
entered, priv is initialized to undefined.

As far as the error being "easy to spot," it seems so to me, but might
not to someone else - so I guess I somewhat agree with your statement
after all - using function declaration instead of a function
expression (where it is valid to do so) would be less error prone.
 
T

Thomas 'PointedEars' Lahn

dhtml said:
Stylistically, I don't like having init routines in a constructor.

Initialization is exactly what constructor code is for.


PointedEars
 
D

dhtml

Initialization is exactly what constructor code is for.

Putting functional code into a constructor is generally considered to
be bad style.

A long constructor is makes changing the code harder. This is
especially true when trying to make a subclass. It also can be a
source of a memory leak because its often used in a way to assign
event handler functions to elements. In other cases, a long
constructor is the result of setting up configuration for the object.

function Menu(el, config){
this.id = el.id;
this.type = config.type;
this.hoverClass = config.hoverClass;
this.disabledClass = config.disabledClass.

et c.
}

Long, messy. Would be better written -

function Menu(el, config) {
this.id = el.id;
this._initConfig(config);
}

- or even -

function Menu(el, config) {
this.id = el.id;
this._config = config;
}

The last one has different implications because the object that
_config holds can exist after the menu instance has been destroyed.
 
P

Peter Michaux

I have seen a couple of ways to define private functions inside other
functions.

1.
var myFunc1 = function() {

function myInnerFunc() {
}

};

2.
var myFunc2 = function() {

var myInnerFunc = function () {
};

};

I use the second option. I haven't been using function declarations
for quite some time now because it makes the code less flexible in
some ways. If you want to wrap the declaration in an if statement then
the function declaration needs to be changed to an expression. If you
want to make the function a property of some object then the
declaration has to be converted to an expression.

With a function declaration the declaration can come after the use of
the function. I don't find this useful or stylistically desirable.

When you use an inner function the inner function is defined each time
the outer function is called. If you don't need this then using an
inner function as above is an expensive way to create "private"
functions. There are other ways to do it.

var myFunc2 = (function() {
var myInnerFunc = function() {
//...
};
return function() {
myInnerFunction();
}
})();
Let's assume that both myFunc1 and myFunc2 have a "public" method also
that calls the "private" method:

This sounds very class-ish which is usually not the best way to think
in JavaScript. That change takes time.
this.init = function() {
myInnerFunc

};

Is there any reason to write/define the private methods one way as
opposed to the other? I am leaning toward using the 2nd way (using var
myInnerFunc = ...) but I cannot give a good reason for choosing this
way instead of the way in #1 above. (I realize that the -- this --
keyword is unavailable in the private method using either construct.)

You can use "this" in the inner function if you call the function with
"Function.prototype.call" or "Function.prototype.apply". These bind
the "this" keyword in the inner function to the first argument in the
call.

var myFunc2 = function() {

var myInnerFunc = function () {
alert(this.x); // do something with "this"
};
this.x = 10;
myInnerFunc.call(this);
};

// Example use will cause the alert to show 10.
({a:myFunc2}).a();

// or
myFunc2.call({})

// or
myFunc2.apply({})

Peter
 
D

dhtml

On Feb 27, 10:36 pm, (e-mail address removed) wrote:

I use the second option. I haven't been using function declarations
for quite some time now because it makes the code less flexible in
some ways.

That is true. The worse thing is that browsers will let you put an FD
(function declaration) in a block, and will behave differently.


If you want to wrap the declaration in an if statement then
the function declaration needs to be changed to an expression. If you
want to make the function a property of some object then the
declaration has to be converted to an expression.

I don't see what you mean. If I want to make the function | m | a
property of an object | x | -

x = { m : m };
function m() {

}

That's perfectly valid. Even if I put the x = {m : m} at the bottom.

With a function declaration the declaration can come after the use of
the function. I don't find this useful or stylistically desirable.

I can see how that could look strange to others. I try to write code
that is easy to understand (see explanation above)
When you use an inner function the inner function is defined each time
the outer function is called. If you don't need this then using an
inner function as above is an expensive way to create "private"
functions. There are other ways to do it.

One of the ways is to have a function that lazily assigns the right
method to the object it is a property of. The way it works is that if
the function is called, it defines a function, then assigns that
function to be the new value of the method.

If you wanted to have conditional logic to define m_priv, then
function expression would be only choice. The benefit would be that
you could do the conditional checks outside of the function, which
would tend to speed up execution of that function when it is called.

var x;

(function(){
x = { m : m };

function m() {
var m,
docEl = document.documentElement;

if("pageYOffset"in window) {
m = function() {
return window.pageYOffset;
};
} else if("scrollTop"in docEl) {
m = function() {
return docEl.scrollTop;
};
}
this.m = m;
return this.m();
}
})();
x.m();

The disadvantage to that is when | x.m | gets renamed to something
more meaningful (x.q, for example), then |this.m = m_priv;| must also
change to |this.q = m_priv;|. It's an ugly dependency that I would
rather avoid.

[snip about call/apply]
 
V

VK

function Menu(el, config){
this.id = el.id;
this.type = config.type;
this.hoverClass = config.hoverClass;
this.disabledClass = config.disabledClass.

et c.

}

Long, messy. Would be better written -

function Menu(el, config) {
this.id = el.id;
this._initConfig(config);

}

- or even -

function Menu(el, config) {
this.id = el.id;
this._config = config;

}

So what is the gain of this approach? You just moved your "mess" from
one place to another. Whatever has to be inited - it has to be inited,
so no matter how many "initConfig" you are using, you still have to
start the actual this.something = something.
Whatever is special to this particular class of objects, it has to be
assigned right in the constructor, whatever is inherited from its
supers must be already here either over the prototype chain or over
super.call(this)
 
T

Thomas 'PointedEars' Lahn

dhtml said:
Putting functional code into a constructor is generally considered to be
bad style.

By whom?
A long constructor is makes changing the code harder.

Non sequitur. Initialization code can be short.
This is especially true when trying to make a subclass.

There are no classes, so no subclasses. And for constructors of derived
prototype objects, that is simply not true.
It also can be a source of a memory leak because its often used in a way
to assign event handler functions to elements.

Non sequitur. Memory leaks can occur everywhere; the important thing is how
try to avoid them. (This is described in the FAQ Notes.)

But, as we have discussed before, it can certainly be useful to define an
object's method to be created in the constructor instead of inherited from
the prototype object. One possibility that readily springs to mind is a
method as a closure defined by the constructor arguments.
In other cases, a long constructor is the result of setting up
configuration for the object.

Long constructors are a product of your imagination.

Sorry, I don't see the distinct advantage in your approach.


PointedEars
 
T

Thomas 'PointedEars' Lahn

dhtml said:
function Menu(el, config){
this.id = el.id;
this.type = config.type;
this.hoverClass = config.hoverClass;
this.disabledClass = config.disabledClass.

et c.
}

Long, messy. Would be better written

.... for example so:

function Menu(el, config)
{
for (var p in config)
{
this[p] = config[p];
}

this.target = el;
}

Incidentally, I am currently using that pattern in a project of mine.
function Menu(el, config) {
this.id = el.id;
this._initConfig(config);

So that's only two lines less now in the constructor (none if you remove the
whitespace). Do you still think it's worth it in this case?
}

- or even -

function Menu(el, config) {
this.id = el.id;
this._config = config;
}

The last one has different implications because the object that
_config holds can exist after the menu instance has been destroyed.

Non sequitur. It keeps existing (until marked for garbage collection) with
any of the presented approaches. Apparently you have failed to recognize
that such an assignment never copies an object, but defines another
reference to it.

It would only make sense to say that the object keeps existing after all
references in the calling execution contexts have been removed.


Please trim your quotes, especially don't quote signatures. ISTM you have
been told that several times before.


PointedEars
 
R

Richard Cornford

Peter Michaux wrote:
With a function declaration the declaration can come after
the use of the function. I don't find this useful or
stylistically desirable.

Just because a function declaration can come after the use of that function
does not mean you have to write your code in that way. It is a commonly
proposed 'best practice' for the layout of code in, say, function bodies to
mirror how that code will be handled. That is, to place inner function
declarations and variable declarations at the beginning of a function body,
in order to reflect the fact that they will be acted upon before the
execution of any function body code. If that practice were followed then
uses of declared functions would always occur after their declarations.

You can use "this" in the inner function if you call the
function with "Function.prototype.call" or
"Function.prototype.apply". These bind the "this" keyword
in the inner function to the first argument in the call.
<snip>

The term "bind" seems inappropriate and potentially misleading here as it
implies some sort of semi-permanent or long term association, while the -
call -and - apply - methods only set the - this - value for the single
function call in question.

Richard.
 
D

dhtml

dhtml wrote:
Non sequitur. It keeps existing (until marked for garbage collection) with
any of the presented approaches. Apparently you have failed to recognize
that such an assignment never copies an object, but defines another
reference to it.

In the first two examples, the properties were copied. The menu did
not have a _config object.

function Menu(el, config){
this.id = el.id;
this.type = config.type;
this.hoverClass = config.hoverClass;
this.disabledClass = config.disabledClass;
}

var c = { type: "sticky", id : "blah", hoverClass : "hover",
disabledClass : "disabled" },
m = new Menu({}, c);

m has its configuration properties copied over from the config object
(config.type, hoverClass, et c). When the menu is destroyed, those
properties (in this case) can't exist anymore.

The same is not true by assigning this.config = config.

The decision to use composition vs. aggregation comes up when
refactoring a long parameter list. This usually leads to an init
routine of some sort. Having an init routine in the constructor is
generally considered bad taste. If you're looking for external sources
on those, Refactoring [Fowler] (long parameter list), Head First OOA&D
(only for the explanation of composition/aggregation and delegation).

Garrett
 
T

Thomas 'PointedEars' Lahn

dhtml said:
In the first two examples, the properties were copied.

You miss the point. I was talking about the object itself. And while the
properties are in a way "copied" in the first example, that does not mean
anything for the property values. See below.
The menu did not have a _config object.

You don't say!
[...] m has its configuration properties copied over from the config
object (config.type, hoverClass, et c). When the menu is destroyed, those
properties (in this case) can't exist anymore.

The same is not true by assigning this.config = config.

It is pretty much the same. As `config' does not need to be an object
reference, its properties do not need to be primitive values.
The decision to use composition vs. aggregation comes up when refactoring
a long parameter list. This usually leads to an init routine of some
sort. Having an init routine in the constructor is generally considered
bad taste.

You are mistaken. It depends very much on the task to be accomplished.
If you're looking for external sources on those, Refactoring [Fowler]
(long parameter list), Head First OOA&D (only for the explanation of
composition/aggregation and delegation).

That's only two resources you cite, of which probably none deals with
ECMAScript in particular, and you actually consider that "generally".

Besides, the question of composition vs. aggregation does not apply to this
situation, it is rather a matter of what one wants to achieve and of
efficiency. ISTM you are confusing object composition with function
composition.


PointedEars
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,819
Latest member
masterdaster

Latest Threads

Top