Forum Moderators: open
like myLib.jsmyLib = { thingie: ..., ... }
which I then load like this<script type="text/javascript" src="myLib.js"></script>
Lately I'm running across stuff
that loads normally like this<script type="text/javascript" src="myLib.js"></script>
but which contains stuff like this(function(myLib){ myLib.thingie = ...; ... })(window);
My Comments:
Re:
(function(myLib){ myLib.thingie = ...; ... }) Re:
(window)
Got any ideas what this is about?
Why would anyone do this?
Why don't browsers barf on the
(window)part?
Can you amplify or elucidate your reply please. I'm sincerely in knowledge-distress about this.
I don't see how
(function(myLib){ myLib.thingie = ...; ... })(window);works and I'd like to take it one step at a time, parsing and interpreting. Perhaps in the process of analyzing it, I'll answer my own questions. 1
function(myLib){ myLib.thingie = ...; ... }Stated loosely and skipping the details, this produces a value which is a functionObjectand gives to it a scope chain that consists of, in this case, a single object: the
globalObject(i.e., the execution context of the HTML script-element).
Comment: The function body containing expressions like this:
myLib.thingie = ...; ..., is compiled. Since myLib is not declared local to the function, the scope chain is traversed seeking a variable named 'myLib'. It is not found, so a global variable is created. Also, since no variable is subsequently assigned the value of the
functionObject, the function remains anonymous.
2
Parentheses, as a pair of tokens, act as a Grouping Operator which, in this case, returns result 1 without applying GetValue to it - adapted from: ECMA-262, section 11.1.6.( Expression )
Comment: I'm unsure what it means to evaluate something without applying GetValue but the implication appears to be twofold: that the result may be of type Reference (a memory address) rather than a value (memory contents), and that no additional error checking is done while producing the result.
3
This is another group that contains the single variable:(window)
window, that returns its value: the
globalObject.
4
This, I think, is the result of the substitutions above. It seems like a very strange construction to me. I have no idea what it is all about and how the execution unit deals with it.functionObject globalObject ;
Questions:
1: In 1, how does the function compiler know that myLib is to be an object rather than just throwing an exception when "myLib.thingie" is encountered?
2: In 1, if myLib is forced to be a global object, what purpose is served by having myLib as a calling argument? - I could speculate or make a surmise but I'd like to know what actually happens at the memory alloc. level. Is this (non-existent) argument necessary?
3: In 1, since the
functionObjectis anonymous, what happens to it when the current line ends? Is the memory freed or does this lead to a memory leak?
(function(){someJScode...})()defines and execute the function immediately.
(function(a,b,c){someJScode...})(e,f,g)
function Z(a,b,c){someJScode...}; Z(e,f,g);
The advantage is that the "anonymous" function is not available in the global scope. It can be used to initialize your library without polluting the global scope with functions and/or variable that have no use past the initialization phase.
Standard method:
var a,b,c;
a=document.getElementById('A');function Z(i) {
do something with i
}
Z(a);
Since Z() is in the global scope, it will be available afterwards, and a page using your script can call it more than once.
anonymous function:
(function(){
var a,b,c;
a=document.getElementById('A');function Z(i) {
do something with i
}
Z(a);
})()
It occurred to me (while dreaming last night!) that in
(function(myLib){ myLib.thingie = ...; ... })(window);, the role of (window);is as part of a call to the anonymous function to pass in the globalObject. So my line of code
(function(myLib){ myLib.thingie = ..., ... })(window); really aught to be (function(globalObject){ globalObject.myLib = {thingie : ..., ... }})(window); What do you think? functionObject globalObject;somehow concatenated two objects and then did something mysterious with the result (which was the part that put me in such knowledge-distress).
Mystery solved. Thanks much!
Edit: Added answers.
Answers:
1: In 1, how does the function compiler know that myLib is to be an object rather than just throwing an exception when "myLib.thingie" is encountered?
Ans: The function compiler doesn't make any such assumption, and it would throw an exception if I had
myLib.myObj.thingiebut doesn't for
myLib.thingiebecause it uses
myLibas the caller's argument (which, in this case, is the
globalObject).
globalObjectto the anonymous function - assumes that the
globalObjectwould otherwise be inaccessible (...is that true?).
[edited by: MarkFilipak at 7:19 pm (utc) on Mar. 20, 2008]
Personally, I don't pass arguments to the anonymous function. Since it's only executed once, I already know what arguments it needs when I write the code.
> Don't try to find a meaning to each part of the contruction.
Why not?
> You can't make it work without one of its components...
> Personally, I don't pass arguments...
Oh sure. Now that I understand what it's doing, I will write this:
or, if I'm not going to "pollute" global, this:(function(){ self.myLib = {thingie : ..., ... }})();
myLib = { thingie: ..., ... }
I didn't write the code. It is part of a library. I don't want to embarrass anyone so I'm not going to disclose from who's library it came, but I will say that you'd recognize it!
Thanks again for your insight. I'm in your debt.
PS: Regarding the use of the anonymous function, do you think my concern about a memory leak has any merit?
[edited by: MarkFilipak at 12:04 am (utc) on Mar. 23, 2008]
If you want a global variable, you don't declare it with "var y;". And if you need a local variable, just use "var z; z=document.getElement...()".
PS: Regarding the use of the anonymous function, do you think my concern about a memory leak has any merit?I don't see why. There are several possibilities of memory leaks with other constructs or events, but not in this case.