new self invoking function

J

Jesse

Hey, I've got a question about self invoking functions in javascript.

What I'm doing is something similar to the following

myNamespace = {}; //namespace for holding any objects/functions

//helpModule as an example
myNamespace.HelpModule = new (function(){
this.abc = '123';
//lots of other code in here...
return this;
})();

However jsLint doesn't like that saying "Weird construction. Delete
'new'.".

But it seems to work fine, and the reason I'm using it is to have
"this" scope to the function instead of the window. I could just
define it as an object literal or do something similar to

myNamespace.HelpModule = (function(){
var obj = {};
obj.abc = '123';

return obj;
}();

but for some reason I like having the 'this' keyword
 
D

David Mark

Hey, I've got a question about self invoking functions in javascript.

What I'm doing is something similar to the following

myNamespace =  {}; //namespace for holding any objects/functions

It's just an object and your code would be clearer without the
comment.
//helpModule as an example
myNamespace.HelpModule = new (function(){
    this.abc = '123';
    //lots of other code in here...
    return this;

})();

Lose the - new - keyword, refactor.
However jsLint doesn't like that saying "Weird construction. Delete
'new'.".

I heartily agree with Douglas on that one. :)
But it seems to work fine, and the reason I'm using it is to have
"this" scope to the function instead of the window.

Not the window, the Global Object.
I could just
define it as an object literal or do something similar to

myNamespace.HelpModule = (function(){
    var obj = {};
    obj.abc = '123';

    return obj;

}();

but for some reason I like having the 'this' keyword

Why? It's a very awkward construct.
 
R

RobG

Hey, I've got a question about self invoking functions in javascript.

What I'm doing is something similar to the following

myNamespace = {}; //namespace for holding any objects/functions

//helpModule as an example
myNamespace.HelpModule = new (function(){
this.abc = '123';
//lots of other code in here...
return this;
})();

All that seems to do is put an extra (useless) object on the returned
object's internal prototype chain. There is no need for the return
statement, functions called with - new - return their this object by
default. A weird construct indeed.

However jsLint doesn't like that saying "Weird construction. Delete
'new'.".

But it seems to work fine, and the reason I'm using it is to have
"this" scope to the function instead of the window. I could just

A function's this keyword has nothing to do with scope, it is a
reference to an object. It is set by the call to the function, you
can't control it by how you create the function other than by limiting
how it is called.
define it as an object literal

Do that - hey look, less code!

var myNamespace = {
HelpModule: {
abc: '123'
}
};

or do something similar to

myNamespace.HelpModule = (function(){
var obj = {};
obj.abc = '123';

return obj;
}();

Which is essentially wrapping an object literal in a function that
just returns the object and possibly creates useless closures. If you
want to use closures for a specific purpose, use the module pattern
(see below). Otherwise why call a function when an object literal will
do the job (and probably do it faster)?

var myNamespace = (function() {

var closedVar_1 = '123';

return {
helpModule: {
getVar_1: function() {
return closedVar_1;
},

setVar_1: function(value) {
closedVar_1 = value;
return closedVar_1;
}
}
}
})();


You may want to read the following blog entry by Peter Michaux:

but for some reason I like having the 'this' keyword

So it's a fashion statement? ;-)

I think Peter gives some good reasons for avoiding the this keyword
with namespaces (in short, because you can't guarantee how a function
will be called so you can't be sure you know what its this keyword
will reference) and provides some alternative strategies.
 
D

David Mark

All that seems to do is put an extra (useless) object on the returned
object's internal prototype chain. There is no need for the return
statement, functions called with - new - return their this object by
default. A weird construct indeed.



A function's this keyword has nothing to do with scope, it is a
reference to an object. It is set by the call to the function, you
can't control it by how you create the function other than by limiting
how it is called.

Thanks for picking that up. Somehow I missed that offending use of
the term. It seems to be so pervasive that virtually every developer
who uses the "major" libraries thinks that scope is the - this -
object; which leaves the question of what they would call the concept
of scope (if they are even aware of the concept).
Do that - hey look, less code!

var myNamespace = {
  HelpModule: {
    abc: '123'
  }

};

That's ideal, but I think they were implying that there would be lots
more inside the one-off function.
Which is essentially wrapping an object literal in a function that
just returns the object and possibly creates useless closures. If you
want to use closures for a specific purpose, use the module pattern
(see below). Otherwise why call a function when an object literal will
do the job (and probably do it faster)?

var myNamespace = (function() {

  var closedVar_1 = '123';

  return {
    helpModule: {
      getVar_1: function() {
        return closedVar_1;
      },

      setVar_1: function(value) {
        closedVar_1 = value;
        return closedVar_1;
      }
    }
  }

})();

You may want to read the following blog entry by Peter Michaux:



So it's a fashion statement? ;-)

This is the new that. :)
I think Peter gives some good reasons for avoiding the this keyword
with namespaces (in short, because you can't guarantee how a function
will be called so you can't be sure you know what its this keyword
will reference) and provides some alternative strategies.

Yes, if a "namespace" object is simply a container for various
functions (to keep the global scope clean), then there is no reason to
rewrite the functions as methods.

This helps with both performance and minification as well as you can
set local references to the functions in the calling code. Those are
two reasons why I went this way with My Library.

I went a long way toward converting Dojo (in my branch) to this
strategy as well. Unfortunately, they decided to un-declare their
global variables instead (ostensibly to make their pervasive lookups
faster). I tried to tell them. :)

Most of the "majors" go all out the other way and constantly reference
their own "namespace" inside of even the most basic functions, which
slows things down and impedes minification.
 
J

John G Harris

It's just an object and your code would be clearer without the
comment.
<snip>

It's an object used to implement a namespace (by hand, as is common in
javascript).

There *should* be a short comment. It should say briefly what this
global variable is for, to be read by maintenance programmers in two
year's time.

What's wrong is the name. When Jesse's code and Jim's code is merged
next year then Jesse's myNameSpace and Jim's myNameSpace will clash
horribly. Also it's far too long to be written many, many times.

John
 
D

David Mark

On Thu, 29 Jul 2010 at 17:46:07, in comp.lang.javascript, David Mark



  <snip>

It's an object used to implement a namespace (by hand, as is common in
javascript).
Yes.


There *should* be a short comment. It should say briefly what this
global variable is for, to be read by maintenance programmers in two
year's time.

The comment seems superfluous to me, particularly due to the name of
the variable, which seems to be self-documenting enough.
What's wrong is the name. When Jesse's code and Jim's code is merged
next year then Jesse's myNameSpace and Jim's myNameSpace will clash
horribly.

Also it's far too long to be written many, many times.

The number of characters typed is never a concern (use an editor with
macros). And in the case of global "namespaces" they shouldn't need
to be written many times (if you do, you are likely writing slow code
that will minify poorly).
 
J

John G Harris

The number of characters typed is never a concern (use an editor with
macros).

No thank you. Some of us are allergic to numerous control codes. They're
for geeks who want to boast about remembering them.

And in the case of global "namespaces" they shouldn't need
to be written many times (if you do, you are likely writing slow code
that will minify poorly).

So you reject the Math object, and would never write a javascript
application that uses lots of mathematical functions.

John
 
D

David Mark

No thank you. Some of us are allergic to numerous control codes. They're
for geeks who want to boast about remembering them.

Who needs macros anyway? It was just an example. Many editors
provide auto-complete features. Furthermore, if you can remember Ctrl
+C and Ctrl+V you are golden. ;)
So you reject the Math object, and would never write a javascript
application that uses lots of mathematical functions.

No, the built-in Math object is not a global "namespace".
 
J

Jesse

Who needs macros anyway?  It was just an example.  Many editors
provide auto-complete features.  Furthermore, if you can remember Ctrl
+C and Ctrl+V you are golden.  ;)





No, the built-in Math object is not a global "namespace".

Thanks for the comments and criticisms :)

Unfortunately I didn't study computer science while at university and
have just picked up programming over the years. So I just wanted to
see if there was something wrong with using that pattern, or is it a
construct? ( these are the sorts of things I now wish I'd learnt while
at Uni)

I wanted to know if it was bad performance-wise, confusing for other's
reading it, or some other implications
It's just an object and your code would be clearer without the
comment.

The comments were the for example's sake
The comment seems superfluous to me, particularly due to the name of
the variable, which seems to be self-documenting enough.

As with the comments this was only named myNamespace for the example.
We use the name of the company which is pretty unique so very unlikely
to clash with anyone else's namespace
 
D

David Mark

Who needs macros anyway?  It was just an example.  Many editors
provide auto-complete features.  Furthermore, if you can remember Ctrl
+C and Ctrl+V you are golden.  ;)

And as for globals, you could peck away for hours using "A" in lieu of
whatever is deemed too typing intensive and then do a global replace
on "A.".

Typing should never be a consideration when naming variables or
properties. And typing the name of a global "namespace" over and over
indicates that inefficiencies are piling up (both in terms of
performance and size).

Math was mentioned as a counter-example (though it is not a global
variable). I suppose you could create local references to its methods
as well, but I'd have to check the specs to be sure that indirect
calls are allowed for all of them.
 
J

John G Harris

Math was mentioned as a counter-example (though it is not a global
variable).
<snip>

Math is a property of the global object. The global object is the
variable object for global vars and functions. Math is accessible from
everywhere.

It's global and it's indistinguishable from a variable. It can only be
'not a global variable' with some weird and unnecessary definition of
global variable.

John
 
D

David Mark

  <snip>

Math is a property of the global object.

Doesn't that go without saying?
The global object is the
variable object for global vars and functions. Math is accessible from
everywhere.

And that.
It's global and it's indistinguishable from a variable.

It is certainly not indistinguishable from a variable.
It can only be
'not a global variable' with some weird and unnecessary definition of
global variable.

That's nonsense.
 
L

Lasse Reichstein Nielsen

John G Harris said:

Well, it depends on what a (global) variable is. Let's for a moment
assume it's something declared using "var" or "function" in the global
scope.

In that case, Math is distinguishable by not being enumerable, whereas
variables are enumerable.

Math can also be deleted (it's configurable), and normal variables
aren't. However, variables introduced using global.eval("var x;")
are actually configurable, and should be considered variables too.

Now, one could also say that this artificial distinction is crap,
and Math acts in every reasonable way as a global variable. And
if it walks like a ducke and quacks like a duck, it must be a
witch^H^H^H^H^Hduck.


Is not! Is so!
What is your reasoning ?

Probably "If I not say this is a variable, this not be a variable!" :p
More seriously, what is needed isn't the reasoning, but just stating
what it means to be "a global variable". After that, it's a matter
of reading to spec to see if Math is one or not, or possibly just
disagreeing with the defintion.

/L
 
J

John G Harris

Well, it depends on what a (global) variable is. Let's for a moment
assume it's something declared using "var" or "function" in the global
scope.

Let's for ever assume it's anything held in a variable object.

Then you can introduce a classification of variables :
Var variables
(with sub-classes declared, implicit)
Function declaration variables
Predefined variables
(with sub-classes primitive, function object, other object)


Probably "If I not say this is a variable, this not be a variable!" :p
More seriously, what is needed isn't the reasoning, but just stating
what it means to be "a global variable". After that, it's a matter
of reading to spec to see if Math is one or not, or possibly just
disagreeing with the defintion.

ECMA262 doesn't define 'variable'.

Are you bidding to be the second PointedEars ?

John
 
D

David Mark


Did you declare it in your code? If so, it's a variable. If not,
it's not. And yes, I am using the term "declare" loosely. Named
arguments and function expressions (the latter of which should be
avoided) count.

The only gray area would be implied global "variables", which are used
without declaration and create properties on the Global Object (which
differ slightly from those created by properly declared global
variables).

Built-in objects, host objects, etc. are not variables. Calling them
as such serves only to create confusion (and there is enough of that
as it is).
 
R

Ry Nohryb

(...) Named
arguments and function expressions (the latter of which should be
avoided) (...)

NFEs ? Avoided ? Why ? NFEs are *not* the problem, the problem is
Microsoft.
The only gray area would be implied global "variables", which are used
without declaration and create properties on the Global Object (which
differ slightly from those created by properly declared global
variables).

Built-in objects, host objects, etc. are not variables.  Calling them
as such serves only to create confusion (and there is enough of that
as it is).

Global symbols: global vars, global objects, global mehtods, etc, all
of them properties of the Global Object (the one that 'window'
aliases)
 
R

Ry Nohryb

baagoe@tournefort:~$ v8
V8 version 1.3.10> window

(shell):1: ReferenceError: window is not defined
window
^

baagoe@tournefort:~$ js
Rhino 1.7 release 2 2010 01 20
js> window
js: "<stdin>", line 2: uncaught JavaScript runtime exception:
        ReferenceError: "window" is not defined.
        at <stdin>:2

$ ~/JAVASCRIPT/v8/shell
V8 version 2.2.8
'window' in this false
var window= this
'window' in this true
this.window [object global]
window.k
'k' in window false
var k= 27
window.k 27

$ /System/Library/Frameworks/JavaScriptCore.framework/Versions/A/
Resources/jsc
this.window undefined
var window= this undefined
this.window [object global]
var k= 27 undefined
27


It comes pre-defined in the browsers.
 
R

Ry Nohryb

Ry Nohryb :

[`window`]
It comes pre-defined in the browsers.

Sure.

My point (I expect you have guessed it) is that one cannot blindly
assume that there is a pre-defined global named "window". ECMAScript
isn't necessarily for browsers. It is a Turing-complete programming
language, and a rather interesting one, too.

I still wonder whether this newsgroup is about browser scripting or about
ECMAScript. It seems to me that most posts would be better placed somewhere
under comp.infosystems.www than under comp.language.javascript, which I
would assume to be about a computing language, not its use in browser
clients in client-server application based on the WWW model, complete with
DOM, compatibility issues, etc. All of which are certainly interesting,
but they have nothing to do with the programming language.

That's because it's the language of the web (browsers). For a long
time most people -even many programmers- didn't even realize that
Java !== JavaScript, and you're expecting them to tell apart the DOM
from the core ? It's a fact that if it were not for the web (browsers)
JS would be completely unknown and irrelevant and dead. Or not?
 
J

John G Harris

Built-in objects, host objects, etc. are not variables.

The appearance of
"the globally defined variable NaN" and
"the globally defined variable Infinity"
in ECMA 262 v3 sec 8.5 suggests that some knowledgeable people disagree
with you.

Calling them
as such serves only to create confusion (and there is enough of that
as it is).

As usual with dogmatic people you have failed to suggest a sensible term
for the general case, in this case covering everything that can be
assigned from and assigned to if not ReadOnly. That's the real recipe
for confusion.

John
 

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
473,995
Messages
2,570,236
Members
46,821
Latest member
AleidaSchi

Latest Threads

Top