Ok guys. I have this basic code which returns a jQuery-esque function called Q.
q=new function(){
var u,q;
q=function Q(slf){
console.log('slf ⇒',slf);
ex=q_ex.call(slf);
console.log('ex ⇒',ex);
};
return q;
function q_ex(){
console.log('this ⇒',this);
return (this!==u && this!==null);
};
};
If I was to call q();. The resulting console display would be:
slf ⇒ undefined
this ⇒ Window {external: Object, chrome: Object, document: document, speechSynthesis: SpeechSynthesis, caches: CacheStorage…}
ex ⇒ true
Now the astute among you will realize that I require this to be undefined and not Window!
Am I missing something here, or does this default to Window if it has the value null or undefined?
I was able to get something working by changing some code around:
var q = (function() {
'use strict';
var u;
function q_ex() {
console.log('this ⇒',this);
return (this!==u && this!==null);
}
return function Q(slf) {
console.log('slf ⇒',slf);
var ex = q_ex.call(slf);
console.log('ex ⇒',ex);
}
})();
q({ foo: 'bar' });
q();
Yes, this tends to default to Window, hence why using new is dangerous. The answer to why you get undefined when printing slf needs a bit more code samples to explain properly, I'll do that when I get home as I'm on my phone at the moment
Edits:
First off I made a bunch of comments to your original code to highlight some problems I found
// Dont use new, its not needed here, use closures
// Also q is not declared here so it will become a global variable, bad bad bad
q=new function(){
// Both declarations are unneeded as you can just return q straight away
// and u never gets a value assigned to it so why declare it?
// If you want to compare with undefined then just write this !== undefined
// Also, refrain from using the same names in nested structures if you value your sanity
var u,q;
// Use either q = function(...){...} or function Q(...){...}
q=function Q(slf){
console.log('slf ⇒',slf);
// ex is not declared with var so this will create a global variable, bad bad bad
ex=q_ex.call(slf);
console.log('ex ⇒',ex);
};
// No need to write the function and then return it.
// Use return(function(...){...}) instead.
return q;
// Just a personal preference but I'd put this before the return
// statement to make it more readable and also use q_ex = function(...){...}
function q_ex(){
console.log('this ⇒',this);
return (this!==u && this!==null);
};
};
Below is how I'd write it
var q = (function(){ // Closure
var q_ex; // Declarations
q_ex = function() { // Internal function
console.log('this ⇒', this);
return (this!==undefined && this!==null);
};
return(function(slf) { // Returned function
console.log('slf ⇒', slf);
var ex = q_ex.call(slf);
console.log('ex ⇒', ex);
});
})(); // Call in the end to get returned function
q() // Returns the same as yours did
q(5) // A numeric object with the value of 5 is now set as 'this'
The way you wrote yours seems to work exactly the same as mine but I cant exactly understand it. Could just be that I'm too deep in the closure religion.
Anyhow, the problem that you had stems from the fact that you run q(), with no parameters. If you ran q(5) you'd see that this becomes 5. This is because if the this parameter is not provided then it defaults to Window. This is the reason new is often dangerous. Say you wrote an object that uses this inside it to store values and thus requires to be created with new. Now if someone created it and forgot to use new you end up polluting the global namespace by attaching all your variables to the Window object (Window === global in browser).
A good way around that risk is to write your objects using closures, that way, how ever they are created they still work the same. You can still access the variables you want from your closing function by just using their name or if you want to group them up somehow just create a single "master" object in your closing function and add everything else into that.
Also, 'use strict' basically disallows some bad practices. Read up on it and use it, makes life easier. Also, use jsHint or any other JavaScript quality checker to help you keep your code clean.
Hope that helped.
Ok guys for anyone watching, I have found my answer. But first, I will clarify a little on the code...
q=new function(){
The reason for using new function is that I had never really used/practiced with self-executing - anonymous functions before and this was the only way I knew how!
q(x) === function Q(x){...}
q is purposefully global!
u is shorthand for undefined, var u === var u=undefined..
It's true I can write this !== undefined, but q_ex() will be used, in future, for multiple object types, from strings to numbers etc...
This level of 'same-name variables' is quite acceptable for it's purpose!
q=function Q(slf){
The reason behind naming the function is purely astetic, and is generally removed once coding is tested.
ex=q_ex.call(slf);
// ex is not declared with var so this will create a global variable, bad bad bad
Well spotted! Though this is a some-what simplified version of the code that is causing the problem, as such ex doesn't need declaring here for the problem to arise.
One last thing... I understand there seems to be no reason for the outer casing of the 'Q' function, but if you look closer... My only global variable is 'q'! If not for the outer casing: u, q, q_ex and any future object would be global and this is NOT the requisite.
Ok then, for my answer...
'use strict';
Function.prototype.call
Strict mode
The solution to my woes...
var q=(function(){
var u,q;
q=function Q(slf){
console.log('slf ⇒',slf);
var ex=q_ex.call(slf);
console.log('ex ⇒',ex);
};
return q;
function q_ex(){
'use strict';
console.log('this ⇒',this);
return (this!==u && this!==null);
};
})();
q();
slf ⇒ undefined
this ⇒ undefined
ex ⇒ false
Thanks for all your help guys, I can now move on with the bigger picture!
I will try to pull myself away from using new function and replace it with (function(){})().
Hope this helps.
Related
Learning about IIFEs i understand that using them does:
not pollute the global scope
shields your code from others.
Could someone please help me understand it better and give a real example of when i could get in trouble when using regular function statement (instead od IIFE?)
Let's say you have a decent sized codebase (a few thousand lines or more). Putting every function on the top level won't be a good idea, because then it'll be pretty easy to accidentally write a function name twice, which will cause bugs due to the name collision. For example:
// code around validating user registration
function validate(username) {
return /someValidationRegex/.test(username);
}
// do stuff with validate
// And then, far elsewhere in the code,
// you need to validate an input for sending to the server:
function validate(input) {
return /someOtherValidationRegex/.test(input);
}
// do stuff with validate
This will not work, because the last validate function will overwrite the first validate function, and the code won't work as expected.
Put each segment of code into an IIFE instead, to avoid the possibility of name collisions:
(() => {
// code around validating user registration
function validate(username) {
return /someValidationRegex/.test(username);
}
// do stuff with validate
})();
(() => {
// code around validating an input for sending to the server:
function validate(input) {
return /someOtherValidationRegex/.test(input);
}
// do stuff with validate
})();
This is the technique that Stack Overflow's Javascript uses (at least in some parts).
Another reason to use IIFEs even if you're careful not to duplicate function names is that you may accidentally duplicate a window property. For example, the following is a somewhat common bug people run into:
// name is defined to be a number...
var name = 5;
// but it's actually a string???
console.log(typeof name);
The problem here is that you're accidentally referring to / overwriting the window.name property on the top level, and window.name may only be a string. There are a whole bunch of functions and variables defined on the top level. To avoid name collisions, put everything into an IIFE instead:
(() => {
// name is defined to be a number...
var name = 5;
// And it's still a number, good
console.log(typeof name);
})();
Still, if your codebase is large enough that name collisions are a decent possibility, rather than manually writing IIFEs, I'd highly recommend using a module system instead, like with Webpack. This will allow you to write modules inside their own encapsulated scope, without leakage or name collisions, and will be more maintainable, when each module only contains exactly the code it needs to run, and nothing more. This makes identifying bugs and extending features much easier than one huge long <script> that you have to navigate through manually.
The common advantage of IIFE is that any "Function or Variable" defined inside IIFE, cannot be accessed outside the IIFE block, thus preventing global scope from getting polluted.
IIFE's are used to define and execute functions on fly and use them on the spot without extra line of Code.
(function(){
var firstName = 'Jhon';
console.log(firstName);
})(); // will be executed on the fly
function test(){
var firstName = 'Jhon';
console.log(firstName);
}
test(); // has to call manually
The IIFE will actually run (immediately-invoked function expression), they don't need a trigger or function call to initiate them, so the variable will be set to its response.
Here's a Fiddle to demonstrate this:
var iffe = (function() {
return 'foo';
})();
var func = function() {
return 'bar';
};
console.log('iife = ' + iffe);
console.log('non-iife = ' + func);
In your JS console you'll see something similar to:
iife = foo and
non-iife = function () {
return 'bar'; }
Also in case we need to pass something in the IFFE scope from the outer scope we need to pass them as a parameter and receive this inside the function defined in the IFFE wrap, something like this -:
var iffe = (function(doc) {
return 'foo';
})(document);
This is a link for some more reference - http://benalman.com/news/2010/11/immediately-invoked-function-expression/
Below is simplification of some code I am trying to understand.
What are we trying to do in this javascript fragment? It seems we are creating object(?) called myCompany if not already created, then adding child object myProject to myCompany.
Then creating a local variable withinmyCompany.myProject and another local to function myCompany.myProject.myfunction. The () at the end make it execute immediately. And we are doing this to keep localVariable_1 out of global space?
var myCompany= myCompany || {};
if (!myCompany.myProject) {
myCompany.myProject = {};
}
myCompany.myProject = function () {
var localVariable_1;
function myFunction(){
var anotherlocalVariable;
// .. do some stuff
}
}();
The first line checks if the object exists, if not use shorthand definition {} to create an Object. || compares. If argument one is null set argument two.
The if on the next line checks if the property myProject isn't set on the object. ! is the operator. If myCompany.myProject returns undefined this if clause returns true. When true create object as property myProject.
Third part: myProject gets replaced by a function object. This function is defined between { and }, but is immediately called upon by the () behind the function declaration.
localvariable_1 will never be in the global scope since it has the var statement. Binding it to the scope of myCompany.myProject function. Maybe this function is directly called to set up some initial values, but wrap them in a function that could be reused to change the values at another moment.
One piece at a time...
var myCompany= myCompany || {};
if myCompany exists you set it to it, otherwise you create an empty object and set myCompany to an empty object.
NOTE: if myCompany already exists you have no indicator of what it is
if (!myCompany.myProject) {
myCompany.myProject = {};
}
Now that you know myCompany is an object you verify it has a project property on it. if not you set myProject to an empty object.
NOTE: you have tested nothing about myProject so again there is no indicator of what it is
myCompany.myProject = function () {
var localVariable_1;
function myFunction(){
var anotherlocalVariable;
// .. do some stuff
}
}();
Here you are assigning myCompany.myProject. Notice at the bottom the () before the ; That makes this function get executed immediately. Inside of the function you are creating another function that currently isn't doing anything. Where you aren't returning from the function I think it will set myProject to undefined.
You may already know what an immediate function is but if not it is basically a function that is called right away. It is also standard to wrap it in a () so that it is easier to read for example
var someFunction = (function () {
/*whatever*/
} ());
You said this was simplified from the original so I am guessing you removed an important part of the code that actually does things but the confusion is probably due to the JavaScript's way of scoping. It uses what is called Lexical scoping. You can think of it as scoping by functions.
Another thing that may be tripping you up is how JavaScript uses truthy evaluation for logical comparisons.
The last thing to mention that might be confusing the way you read the code is javascript's hoisting.
Hopefully that helps or at least points you to a few things you can look into to figure out the parts you don't exactly understand.
Sorry I just hate writing in comments lol.
If you are trying to help prevent your global scope from getting polluted then you might want to use objects and a something similar to what you are doing. Depending on how crazy you want to get you could look into Prototypical Inheritance.
A common pattern is to do something like this
var company = (function() {
var name;
var getName = function() {
return name;
};
var setName = function(n) {
name = n;
};
return {
getName : getName,
setName : setName
}
}())
Now you can do company.setName("yoda") or whatever.
This will give you a basic getter and setter where no one can change the companies name without going through your getter and setter and it also doesn't pollute the global scope. You can have whatever you want on company this way and you also encapsulate the data within the object.
Notice how var company = a function that is called immediately which returns an object that has whatever you want to encapsulate on it.
Is that what you are talking about?
I know this subject had been dealt a lot here, but I saw this specific example on the Pluralsight JS design pattern course, and I'll be glad for your help understanding the closure there.
This is the example:
var Calc = function(start) {
var that = this;
this.add = function(x) {
start = start + x;
return that;
};
this.multiply = function(x) {
start = start * x;
return that;
};
this.equals = function(callback) {
callback(start);
return that;
};
}
new Calc(0)
.add(1)
.add(2)
.multiply(3)
.equals(function(result){
console.log(result); // returns 9
});
Here's the JSFiddle link: http://jsfiddle.net/3yJ8Y/5/
I'll be VERY glad for:
Understanding the "that" use. Why do we need it in this specific
example? it does the same with "this". Can you pls give examples and explain when do we need to do "var that = this"?
Understanding this way of creating functions from an object. why do we have to use "this" and then .functionName? like this.add = ...
A detailed and extensive explanation for this very specific closure example.
Thank you so much!
start becomes a global variable of the Calc object
Each method of the Calc object (add, multiple, equals) references that same global variable
new Calc(0) // <- sets start to 0
.add(1) // calls add() <- sets start to 1
.add(2) // calls add() <- sets start to 3
.multiply(3) // calls multiple() <- sets start to 9
.equals(function(result){
console.log(result); // returns 9
});
Thanks to #elclanrs for reminding me of things I had internalized and forgotten...
That
The important thing here is that that... is unnecessary.
I'll quote an article that #elclanrs linked in his comment on the above post:
Scope In Javascript
JavaScript establishes an execution context for the function call, setting this to the object referenced by whatever came before the last ”.”
Because each method is called with the outer Calc before it's dot, the this value inside that method is assigned as the outer object.
The outer object, in turn, is its own brand new, self-contained scope because it was created with the new keyword:
When new[Calc]() is executed, a completely new object is created transparently in the background. [Calc] is called, and its this keyword is set to reference that new object.
(Scope in Javascript, again, with my edits in brackets).
Now you might be wondering, "How is this:
.add(1)
.add(2)
.multiply(3)
... keeping the right scope? You said that whatever is before the . is passed in as the this variable in this situation!?"
Absolutely true, and in this situation, each method is returning this, which allows method chaining. (They're actually returning that, but we already determined that was an unnecessary variable in this context).
Why use that
First of all, let me say I prefer var self = this over var that = this but there are arguments either way.
Let's arbitrarily modify the object to have a method that looks like this:
this.getInternalThis = function(){
var internalThis = function(){
console.log( this );
}
}
First of all, let's get this out of the way: this example is stupid, but you'll see things like this - a function defined in other scopes - all the time.
Here are the important things to notice:
It's called by name, and nothing more (no prefixed . notation, for example)
... that's it!
When a function is called this way, the engine has to figure out something to assign this as in the scope of the function. It defaults to window.
If you were to run this code, you would get Window in the console.
Now, what if we wanted this inside that internal function call to be the calling value of this?
This situation is where you need a that variable. We can modify the function to look like:
this.getInternalThis = function(){
var that = this,
internalThis = function(){
console.log( that );
};
}
Now when you run this method, you get the value of the calling object in the console.
In my case it was Object { add=function(), multiply=function(), equals=function(), getInternalThis=function()}.
Sometimes, that's what you need or expect, so that's why you would use a var that = this declaration.
Using this. to define a method
As I mentioned earlier:
Because each method is called with the outer Calc before it's dot, the this value inside that method is assigned as the outer object.
Remember that this in the scope of Calc() is a reference to the new Calc object, so each method is being given the Calc object as the value of this (remember, it's before the .!) when they enter their new scope from that context.
Hopefully this gives you a little info on how JavaScript scopes and the assignment of this works.
I like the revealing module pattern. I will have private functions that I would like to make public and return them. But I may also have some local functions within my revealing module pattern that "return this"...
var player = function(){
//my local variable scope...
oplayer.damage = function(){
if(!this.grace){
this.shield--;
if (this.shield == 0){
return this;
}
}
};
...
return {
damage : oplayer.damage
}
}();
Is it ok to "return this" if I am explicitly returning something? (in context to using the revealing module pattern). If not, how can I transform my local function oplayer.damage to be used in a proper context? Thanks for any advice! I'm just trying to wrap my mind around the whole "return this" concept.
It should be fine, because "this" is contextual to execution. Because you're returning this on a public function which is part of the "cut down" object, then you'll only get the cut down object. So, I think what you're trying to do should be fine if you consider the following scenarios:
var test = function(){
var pri = function(){
console.log("Private");
};
var pub = function(){
pri();
console.log("pub");
return this;
}
return {
pub: pub
};
}();
console.log(test.pri); //-> undefined
console.log(test.pub); //-> function(){…}
console.log(test.pub()); //-> "Private" "pub" [Object {…}]
console.log(test.pub().pri); //-> "Private" "pub" undefined
Please first check out what the this keyword is, there is a good introduction at MDN.
Is it ok to "return this" if I am explicitly returning something?
Yes, of course. This is the default pattern for chainability of methods - everything returns the object it was called on. However, to rely on that you'd need to return it in every case, not only when the shields are down.
If this wasn't your aim, just use a normal return; statement (results in undefined as like as no return statement).
in context to using the revealing module pattern
It does absolutely not matter where you defined that function.
transform my function to be used in a proper context?
(I assume with "context" you refer to the this object here)
You can't really, the value of this always depends on the invokation of the function. Of course, you could .bind() the function to your player object or just directly only return player instead of this.
I always use the following self executing function in order to avoid exposing my code to global scope in JavaScript:
(function() {
//Code comes here
})();
I believe that this is also called self executing anonymous function as well. Sometimes, I also see the below code used for the same purpose:
(function(d){
//Code comes here
})(document.documentElement);
I am not sure what makes the difference here so I am asking this question.
What is the difference (or are the differences) between these two types of self executing function on JavaScript?
The code below demonstrates what's happening. In reality, the foo and bar variables don't exist, and the functions are anonymous.
var foo = function() {}
foo();
var bar = function(d){}
bar(document.documentElement);
The (function(d){})(d) method is called a closure. It's used to pass variable values which are subject to change, such as in loops.
Have a look at a practical an example:
for(var i=0; i<10; i++) {
document.links[i].onclick = function(){
alert(i); //Will always alert 9
}
}
After implementing the closure:
for(var i=0; i<10; i++) {
(function(i){
document.links[i].onclick = function(){
alert(i); //Will alert 0, 1, ... 9
}
})(i);
}
Remember that function arguments and variables are the same thing, deep down.
The second example is (basically) just shorthand for
(function(){
var d = document.documentElement;
}());
since it avoids the need for the var and the =.
There are some common uses for this pattern:
Creating lexically scoped variables (just remembered this after seeing Rob's answer...)
//this does not work because JS only has function scope.
// The i is shared so all the onclicks log N instead of the correct values
for(var i = 0; i< N; i++){
elems[i].onclick = function(){ console.log(i); }
}
//Each iteration now gets its own i variable in its own function
// so things work fine.
for(var i=0; i<N; i++){
(function(i){
elems[i].onclick = function{ console.log(i); };
}(i));
}
In this case, passing the parameters directly allows us to reuse the same variable name inside, in a way that var i = i would not be able to. Also, the conciseness is a benefit, since this is just a boilerplate pattern that we don't want to dominate over the important code around it.
It makes it easy to convert some old code without having to think too much about it
(function($){
//lots of code that expected $ to be a global...
}(jQuery)) //and now we can seamlessly do $=jQuery instead.
Parameters that are not passed are set to undefined. This is useful since normally undefined is just a global variable that can be set to different values (this is specially important if you are writing a library that needs to work w/ arbitrary third party scripts)
(function(undefined){
//...
}())
The first function takes no parameters. The second one takes a single parameter. Inside the function, the parameter is d. d is set to document.documentElement when the function is called.
It looks like the author of the second code wants to use d as a shorter way to write document.documentElement inside the function.
if you want to pass arguments to the self executing anonymous functions, use the second one. It might come in handy when you want to use variables in the function that have the same name with others in the global scope :
var a = "I'm outside the function scope",
b = 13;
alert(a);
alert(b);
(function(a,b){
// a is different from the initial a
alert(a);
// same goes for b
alert(b);
})("I'm inside the function scope",Math.PI);
It can also be useful to use something like :
var a;
console.log(a === undefined); // true
undefined = true;
console.log(a === undefined); // false
(function(undefined){
console.log(a === undefined); // true, no matter what value the variable "undefined" has assigned in the global scope
})();
when trying to implement the null object design pattern
If you are concerned about efficiency, you might end up using something like this :
var a = 2;
(function(window){
alert(a);
// accessing a from the global scope gets translated
// to something like window.a, which is faster in this particular case
// because we have the window object in the function scope
})(window);
One reason for using the second form, with the argument, is that insulates your code against other js code loaded later on the page (eg other libraries or framework code) that might re-define the variable passed in as the argument.
One common example would be if the code within your self-executing anonymous function relies upon jQuery and wants to use the $ variable.
Other js frameworks also define the $ variable. If you code your function as:
(function($){
//Code comes here
})(jQuery);
Then you can safely use $ for jQuery even if you load some other library that defines $.
I have seen this used defensively with people passing in all the 'global' variables they need inside their block, such as window, document, jQuery/$ etc.
Better safe than sorry, especially if you use a lot of 3rd party widgets and plugins.
Update:
As others have pointed out the set of parentheses around the function are a closure. They are not strictly neccessary a lot of times where this pattern is used (#Rob W gives a good example where they're essential) but say you have a very long function body... the outer parentheses say to others reading the code that the function is probably self-executing.
Best explanation I saw of this pattern is in Paul Irish's video here: http://paulirish.com/2010/10-things-i-learned-from-the-jquery-source/ starting about 1:30
This SO question also has some informative answers: How do you explain this structure in JavaScript?