Using "new function() {...}" as a Singleton

R

Richard Cornford

new expression is basically an "elegant" module pattern
recognizable since the beginning.

var o = (function () {}());

what can "o" be? just everything, included undefined.

Might this not be a case of solving the wrong problem? Wouldn't it be
possible to chose an Identifier for use in place of 'o' that told the
reader of the code enough about the value that the variable was
expected to hold that they did not need to look any further unless
debugging showed evidence that the actual value was not consistent
with the expectation?
var o = new function () {};

what can "o" be in above case? Inevitably an object ;-)
<snip>

An object, but not necessarily the object that resulted from - new -
operation, and possibly a function, Date, RegExp, String, host, etc.
object. The use of the - new - operator really only grantees that the
value will not be a primitive, which isn't such a great step forward.

Richard.
 
T

Thomas 'PointedEars' Lahn

David said:
Good, except the last parenthesis is in the wrong spot.
^^^^^^^^^^
Opinions differ there.
Too bad it is the wrong answer. :)
Pardon?

Don't use that.

Not so at least. An implementation that does not support object
initializers could support anonymous function expressions; but it is
unlikely that it would not support the Object constructor/factory then.


PointedEars
 
T

Thomas 'PointedEars' Lahn

Thomas said:

Ahh, did you mean the more specific "`o' must be the identifier of a
variable that has a reference to an object as its value"?


PointedEars
 
D

David Mark

Thomas said:
Ahh, did you mean the more specific "`o' must be the identifier of a
variable that has a reference to an object as its value"?

No, my quoting obscured the fact that I was remarking on the pattern
choice. See follow-ups.
 
A

Andrea Giammarchi

I don't know.  I stopped reading after that.  ;)

I know what I wrote may not be clear for developers new JS, but did
you actually get anything I wrote?

That invocation was an example with absolutely nothing wrong in therm
of parenthesis. I have already described in my blog the reason I think
(function () {}()) is better than (function () {})() have a look.

About the fact there is nothing inside was, again, an example ...
whatever you return, included undefined ... this is *not* true with
new function () {}, is this difficult to understand as concept? I
think others got it, keep reading the rest.

About all those arguments unrelated stories, you should read and try
to understand and eventually ask what is not clear, before you start
talking about flies and flowers ... I was simply explaining
differences and whatever is not clear I can explain again.

Please do not scam this ml with always your library ...it's quite
boring, isn't it?

best Regards
 
D

David Mark

Andrea said:
I know what I wrote may not be clear for developers new JS, but did
you actually get anything I wrote?

See above.
That invocation was an example with absolutely nothing wrong in therm
of parenthesis.
IBTD.

I have already described in my blog the reason I think
(function () {}()) is better than (function () {})() have a look.

No thanks.
About the fact there is nothing inside was, again, an example ...
whatever you return, included undefined ... this is *not* true with
new function () {}, is this difficult to understand as concept? I
think others got it, keep reading the rest.

I'd just as soon not, but thanks again.
About all those arguments unrelated stories, you should read and try
to understand and eventually ask what is not clear, before you start
talking about flies and flowers ... I was simply explaining
differences and whatever is not clear I can explain again.

Clear as mud (as usual). Almost VK-esque. I can rarely make heads or
tails of your stuff (the prose, not the script).
Please do not scam this ml with always your library ...it's quite
boring, isn't it?

Even if you meant _spam_ this _ng_, you would still be wrong.
best Regards

Same! :)
 
D

dhtml

Might this not be a case of solving the wrong problem? Wouldn't it be
possible to chose an Identifier for use in place of 'o' that told the
reader of the code enough about the value that the variable was
expected to hold that they did not need to look any further unless
debugging showed evidence that the actual value was not consistent
with the expectation?



<snip>

An object, but not necessarily the object that resulted from - new -
operation, and possibly a function, Date, RegExp, String, host, etc.
object. The use of the - new - operator really only grantees that the
value will not be a primitive, which isn't such a great step forward.

With `new`, the invocation is at the beginning of an expression so it
is immediately apparent. With a CallExpression it is at the end.

var animalBuilder = new function() {
/*...*/
};

As you pointed out, a constructor may have an explicit return
statement and return an object. But if it is used with a
NewExpression, why would it?

An anonymous function might have any reason for not being called
immediately. There is a lot of code that does things like that and for
good reason. For example:

var animalBuilder = function() {
/*...*/
};

A NewExpression with a FunctionExpression is perfectly valid and fine
to use. The only problem is confusion, which has been demonstrated by
the misconceptions that have been posted. Those misconceptions are:

1) it might not return an object
2) it is an awful choice
3) it cannot accept Arguments

1) False. A new expression will always result in an object being
created and returned unless the function throws an error.
2) In the right context, it is a good option
3) False, as shown

It is confusing to beginners. Like anything, there is potential for
misuse. One type of misuse is where only a closure is needed and the
code does not assigning to `this` and discards the result.

Using new expression with function expression is fine. Once the
mechanics are understood (and they really are quite simple), the
pattern should not be confusing.
 
A

Asen Bozhilov

dhtml said:
A NewExpression with a FunctionExpression is perfectly valid and fine
to use. The only problem is confusion, which has been  demonstrated by
the misconceptions that have been posted. Those misconceptions are:
3) it cannot accept Arguments

That statement is not correct. The semantic of NewExpression by
ECMA-262 is:

| new NewExpression
| new MemberExpression Arguments

So the follow code is valid and pass list of arguments to internal
[[Construct]] method of the object referred by the value of
MemberExpression.

new function(x, y){
print(x * y); //10
}(2, 5);

Of course that code is confused, especially for beginners. The whole
point with passing arguments to FunctionExpression which is called
right after creation, is useless practice. FunctionExpression itself
is lexical closure, because during evaluation of FunctionExpression,
will be created object on which internal [[Scope]] property refer AO/
VO of execution context in which is evaluated that FunctionExpression.
From that point, every FunctionExpression called right after creation
can get the values of variables/functions defined in calling execution
context via Scope Chain.

Usually that approach is used for lookup optimizations, which is
complete useless, especially in this way.
 
D

David Mark

dhtml said:
With `new`, the invocation is at the beginning of an expression so it
is immediately apparent. With a CallExpression it is at the end.

var animalBuilder = new function() {
/*...*/
};

As you pointed out, a constructor may have an explicit return
statement and return an object. But if it is used with a
NewExpression, why would it?

An anonymous function might have any reason for not being called
immediately. There is a lot of code that does things like that and for
good reason. For example:

var animalBuilder = function() {
/*...*/
};

A NewExpression with a FunctionExpression is perfectly valid and fine
to use. The only problem is confusion, which has been demonstrated by
the misconceptions that have been posted. Those misconceptions are:

1) it might not return an object
2) it is an awful choice

The only confusion there was your own.
3) it cannot accept Arguments

1) False. A new expression will always result in an object being
created and returned unless the function throws an error.
2) In the right context, it is a good option

To wit. Presented with a choice of two patterns that produce the same
result, an argument promoting the usefulness of the result is obviously
a non-argument.
 
D

Dmitry A. Soshnikov

On 22.05.2010 3:01, Asen Bozhilov wrote:

[...]
Usually that approach is used for lookup optimizations, which is
complete useless, especially in this way.

Why is it useless? Name binding is present in the activation object, but
not in some parent variable objects.

There is a known disadvantage of course of such style -- you have to
scroll code down to see, what is the passed value of formal parameter.
Moreover, I think, that this style is the result of doubtful "coolness"
when some has found out, that JS "can do so".

The preferred is to define just local variables (which the same as
formal parameter bindings are in the activation object) with the same
values. E.g.:

(function () {
var document = document;
...
})();


Nevertheless, there is one difference in case when a value is passed via
formal parameter -- it will be assigned on entering the context stage.
In contrast with defining local variable which real value (but the
default /undefined/) is assigned at code execution phase. From this
viewpoint, a variable has /two/ assignments.

But, repeat, from the human code building, passing a value via parameter
is less convenient, so personally, I would prefer to define a local
variable.

Dmitry.
 
R

Ry Nohryb

(...)
But, repeat, from the human code building, passing a value via parameter
is less convenient, so personally, I would prefer to define a local
variable.

I don't:

aQuery= (function (o, where, attr, value) {
return (o.refresh= function (set, i, e) {
o.length= 0, i= (set= where.getElementsByTagName('*')).length;
while (i--) ((e= set)[attr] === value) && (o[o.length]= e);
return o;
})();
})([], document.body, "width", "100%");

aQuery.forEach(function (value, index, obj) { ... });
..
..
..
aQuery.refresh().forEach(function (value, index, obj) { ... });
 
A

Asen Bozhilov

Dmitry said:
Asen Bozhilov wrote:

Why is it useless? Name binding is present in the activation object, but
not in some parent variable objects.
The preferred is to define just local variables (which the same as
formal parameter bindings are in the activation object) with the same
values. E.g.:

(function () {
   var document = document;
   ...

})();

You give the answer. I prefer to define local variables, too. When
variables are defined on the top of the function code, the code is
consistence and the reader can easy understand which values hold those
variables. The maintaining of the code is better, because you can easy
change the values of your local variables without scroll up and down.

The only one case where can be used that approach is when someone want
to share the `this' value of calling execution context to created by
execution of that FunctionExpression. For exampple:

(function (callingThis) {
//....
})(this);
 
D

David Mark

Ry said:
(...)
But, repeat, from the human code building, passing a value via parameter
is less convenient, so personally, I would prefer to define a local
variable.

I don't:

aQuery= (function (o, where, attr, value) {
return (o.refresh= function (set, i, e) {
o.length= 0, i= (set= where.getElementsByTagName('*')).length;
while (i--) ((e= set)[attr] === value) && (o[o.length]= e);
return o;
})();
})([], document.body, "width", "100%");


That may be the most god-awful, convoluted mess I've ever seen (and I've
seen jQuery, Dojo, etc., so that's really saying something). You're
fired, El Abuelo. :)
 
R

Ry Nohryb

Ry said:
aQuery= (function (o, where, attr, value) {
 return (o.refresh= function (set, i, e) {
   o.length= 0, i= (set= where.getElementsByTagName('*')).length;
   while (i--) ((e= set)[attr] === value) && (o[o.length]= e);
   return o;
 })();
})([], document.body, "width", "100%");


That may be the most god-awful, convoluted mess I've ever seen (and I've
seen jQuery, Dojo, etc., so that's really saying something).


It's awesome, yeah, truly awesome. And didactic, too: it shows that
expressions' values are there for you to use them, that local vars are
not any better than named params, that immediate function calls
provide a good chance to initialize all of them on the fly using 0
additional lines, that the var keyword is often superfluous, that
boolean operators are perfect flow controllers, that it's useless to
wrap single-line blocks in braces, and that JS can be made to look
very much like the most delightful of C code.
You're fired, El Abuelo.  :)

Nah!
 
D

Dmitry A. Soshnikov

Ry said:
aQuery= (function (o, where, attr, value) {
return (o.refresh= function (set, i, e) {
o.length= 0, i= (set= where.getElementsByTagName('*')).length;
while (i--) ((e= set)[attr] === value)&& (o[o.length]= e);
return o;
})();
})([], document.body, "width", "100%");


That may be the most god-awful, convoluted mess I've ever seen (and I've
seen jQuery, Dojo, etc., so that's really saying something).


that local vars are
not any better than named params,


Of course they are not (and local vars even worse from the already
mentioned viewpoint -- they have /two/ assignments (initial - on
entering, and real - at execution)).

The only lack (and is very inconvenient lack) is that I (analyzing your
code) should (and we suppose it's more than you small example with 7
lines) scroll first to the end (to the call expression) to see, what are
the values of some strange names "o, where, attr, value" and then go
back to continue analyze the code -- yes, again scrolling up.

That's it. There is no any other lacks and from the assignments "issue"
formal parameter for that purpose even win the local vars.

that immediate function calls
provide a good chance to initialize all of them on the fly using 0
additional lines,

Yes, that's true. Also there is one important exception when passing via
formal parameter is needed -- already mentioned by Asen passing /this/
value (if you assumes that inside the function context it will have
other value).
that the var keyword is often superfluous

It's the matter of taste. So let's leave it for that. Everyone can
choose his own style. There are pros and cons. And if in case of local
vars cons are mostly theoretically-technical (/two/ assignments -- who
cares?), then in case of passing via arguments cons are exact and real
-- inconvenience for a programmer.

Tacking into account that both name binding will be in the same place (a
property of an activation object), I prefer to use local vars. But, it
isn't my rule -- I do so most the time, but also can be a case whey I
pass them via arguments. Why? Because I just want so and free to do so.
that
boolean operators are perfect flow controllers,

Is it about the topic or this is about something else? Show me an example.
that it's useless to
wrap single-line blocks in braces,

The same, I didn't get it. Is it relevant or this is from other song?
And by the way, wrapping a single-line block in braces can also for
convenience: var a = (bla ? blu : ble). It's just a matter of taste.

Dmitry.
 
R

Ry Nohryb

Of course they are not (and local vars even worse from the already
mentioned viewpoint -- they have /two/ assignments (initial - on
entering, and real - at execution)).

The only lack (and is very inconvenient lack) is that I (analyzing your
code) should (and we suppose it's more than you small example with 7
lines) scroll first to the end (to the call expression) to see, what are
the values of some strange names "o, where, attr, value" and then go
back to continue analyze the code -- yes, again scrolling up.

That's it. There is no any other lacks and from the assignments "issue"
formal parameter for that purpose even win the local vars.


function qGen (o, where, attr, value) {
return (o.refresh= function (set, i, e) {
o.length= 0, i= (set= where.getElementsByTagName('*')).length;
while (i--) ((e= set)[attr] === value) && (o[o.length]= e);
return o;
})();
}

aQuery= qGen([], document.body, "width", "100%");

Yes, that's true. Also there is one important exception when passing via
formal parameter is needed -- already mentioned by Asen passing /this/
value (if you assumes that inside the function context it will have
other value).

But that's not any "important exception", afaics, for you can't shadow
"this". Passing it as a parameter just captures it, no matter what it
is, be it the outer this or anything else.
It's the matter of taste. So let's leave it for that. Everyone can
choose his own style. There are pros and cons. And if in case of local
vars cons are mostly theoretically-technical (/two/ assignments -- who
cares?), then in case of passing via arguments cons are exact and real
-- inconvenience for a programmer.

Tacking into account that both name binding will be in the same place (a
property of an activation object), I prefer to use local vars. But, it
isn't my rule -- I do so most the time, but also can be a case whey I
pass them via arguments. Why? Because I just want so and free to do so.

I usually declare locals as params.
Is it about the topic or this is about something else? Show me an example..

That instead of if (a) { b() } you can just write a && b();
The same, I didn't get it. Is it relevant or this is from other song?
And by the way, wrapping a single-line block in braces can also for
convenience: var a = (bla ? blu : ble). It's just a matter of taste.

Yes, this parens are useless, where do they come from ? :)
 
D

David Mark

Ry said:
Of course they are not (and local vars even worse from the already
mentioned viewpoint -- they have /two/ assignments (initial - on
entering, and real - at execution)).

The only lack (and is very inconvenient lack) is that I (analyzing your
code) should (and we suppose it's more than you small example with 7
lines) scroll first to the end (to the call expression) to see, what are
the values of some strange names "o, where, attr, value" and then go
back to continue analyze the code -- yes, again scrolling up.

That's it. There is no any other lacks and from the assignments "issue"
formal parameter for that purpose even win the local vars.


function qGen (o, where, attr, value) {
return (o.refresh= function (set, i, e) {
o.length= 0, i= (set= where.getElementsByTagName('*')).length;
while (i--) ((e= set)[attr] === value) && (o[o.length]= e);
return o;
})();
}

aQuery= qGen([], document.body, "width", "100%");

Yes, that's true. Also there is one important exception when passing via
formal parameter is needed -- already mentioned by Asen passing /this/
value (if you assumes that inside the function context it will have
other value).

But that's not any "important exception", afaics, for you can't shadow
"this". Passing it as a parameter just captures it, no matter what it
is, be it the outer this or anything else.
It's the matter of taste. So let's leave it for that. Everyone can
choose his own style. There are pros and cons. And if in case of local
vars cons are mostly theoretically-technical (/two/ assignments -- who
cares?), then in case of passing via arguments cons are exact and real
-- inconvenience for a programmer.

Tacking into account that both name binding will be in the same place (a
property of an activation object), I prefer to use local vars. But, it
isn't my rule -- I do so most the time, but also can be a case whey I
pass them via arguments. Why? Because I just want so and free to do so.

I usually declare locals as params.


LOL. I declare you incomprehensible.
That instead of if (a) { b() } you can just write a && b();

Yes, in CS such "cute" constructs are known as "job security". In
business it is known as being a complete prat who should be shown the
door immediately. Hasta la vista El Abuelo!
Yes, this parens are useless, where do they come from ? :)

They are useless in that case. But where do you come from? :)
 
D

Dmitry A. Soshnikov

Of course they are not (and local vars even worse from the already
mentioned viewpoint -- they have /two/ assignments (initial - on
entering, and real - at execution)).

The only lack (and is very inconvenient lack) is that I (analyzing your
code) should (and we suppose it's more than you small example with 7
lines) scroll first to the end (to the call expression) to see, what are
the values of some strange names "o, where, attr, value" and then go
back to continue analyze the code -- yes, again scrolling up.

That's it. There is no any other lacks and from the assignments "issue"
formal parameter for that purpose even win the local vars.


function qGen (o, where, attr, value) {
return (o.refresh= function (set, i, e) {
o.length= 0, i= (set= where.getElementsByTagName('*')).length;
while (i--) ((e= set)[attr] === value)&& (o[o.length]= e);
return o;
})();
}

aQuery= qGen([], document.body, "width", "100%");


I don't understand the goal of what you're trying to show me. I
understand, you're saying something like: "look, it's the same if I
declare function first and the call it" -- but that's irrelevant with
the case. You was talking about some "useless additional line" provided
by the local "var" and then show me the same additional line by calling
the function after its definition.

What's the goal of your writing? Are you trying to prove me something or
to say that passing via arguments (in /concrete relevant case/ --
immediate invocation of an FE) is better? I thought we've already
decided that this is the matter of taste and describe pros and cons of
both variants. Or I missed something?
But that's not any "important exception",

For me, it is.
afaics, for you can't shadow
"this".

What do you mean, shadow /this/ ? I don't wanna shadow /this/, I just
want to get /this/ value of the caller in a view of a formal parameter.
Passing it as a parameter just captures it, no matter what it
is, be it the outer this or anything else.

That exactly I want, and nothing else.
I usually declare locals as params.

That's your choice, you're free in it, nobody says that it's worse. I
just said that it will be inconvenient for me to scroll down first, and
then scroll up back. That's it. There is no need to show some
alternative examples with separating definition and execution of a
function, I understand the goal and see pros and cons.
That instead of if (a) { b() } you can just write a&& b();

Yes, I like it also in some cases (mostly, when conditions is simple --
with one-two predicates). If condition is more complex, I prefer /if/.
Yes, this parens are useless, where do they come from ? :)

The definition of a "uselessness" is just in your head and depends on
your habit and taste. Let's say correctly: (1) it isn't required, but
(2) everyone can use it if it is convenient for him, e.g. to group (with
a /grouping/ operator, notice) some logical parts. Personally, I again
can use both cases and think that it isn't worth to talk about it on 10
pages ;)

Dmitry.
 
D

David Mark

Johannes said:
David Mark :


Not in CS, in IT, which is quite different.

Well, I first heard it from a CS professor. He was describing a very
obtuse construct, not unlike El Abuelo's examples.
Both are important, neither
should dismiss the other's concerns.

Who's dismissing?
After all, they both benefit a lot
one from another.

Yes. And neither benefits from bad code.
 

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

Forum statistics

Threads
474,079
Messages
2,570,573
Members
47,205
Latest member
ElwoodDurh

Latest Threads

Top