var variableOne;
var variableTwo;
var variableThree;
function veryInterestingFunction() {
var variableFour;
if(a){
variableFour = 'Good';
}
else {
variableFour = 'Decent';
}
console.log(variableFour);
}
$(window).on('scroll', function(){
veryInterestingFunction();
});
Here I have some variables in the global scope, a function declaring a variable and assigning a value to it, and calling this function on scroll.
This way on every scroll you are going to declare the "variableFour" which is not a good practice, right?
However I don't want to crowd the global scope with unnecessary variables and also can't use an IIFE. Is there a "best practice" way to declare the variable outside the function and still only possible to use it inside the scope of that function ?
http://jsfiddle.net/2jyddwwx/1/
to declare the variable outside the function and still only possible to use it inside the scope of that function ?
I guess, that's impossible
When I don't want to crowd the global scope, I will declare one global object, for example App = {}, and instead of global variables, I use it's properties.
App.variableOne;
App.variableTwo;
App.variableThree;
Or you can use classes in ES6
I don't think there's anything wrong with your code sample, I seriously doubt variable declaration is ever going to slow down your code. I'd definitely only start to worry about this kind of thing when you're absolutely certain it's causing issues (it won't), otherwise it might be wasted effort.
If you really want to optimize this, one thing you might be able to do is debouncing the veryInterestingFunction calls - that is if you don't necessarily need to respond to every single scroll event (depends on your logic).
As per your question, IIFE/function closure is essentially the only way to limit scope in JavaScript that I know of, so if you can't use that, I don't see any other option.
There is no problem in declaring an empty variable into your scope. If it is not global, it belongs to the scope.
And there is no need to fear for performance. If you declare variables within your scope, the Javascript garbage collector will empty that for you. Take a read at this article
Related
Can somebody please explain me why the following code works?
function getLastName()
{
fullName.lastName = "World";
}
function writeName()
{
fullName = {};
fullName.firstName = "Hello";
getLastName();
document.write(fullName.firstName + " " + fullName.lastName);
}
writeName();
For some reason, getLastName() can reach local its enclosing method's local state. How can this work? And also should I utilize this feature of Javascript or it is considered as a bad practice? If it is a bad practice, could you please explain why?
You can see the actual code working here at http://jsbin.com/atituk/2/edit
You don't have any local variables, that would require using the var keyword. All your variables are global and can be accessed anywhere within window, which is not considered good practice at all.
You have not used the var keyword against fullName inside the writeName function, you are therefore taking it from the scope outside writeName. It continues up the chain until it reaches the outer most scope, at which point it creates a global.
Globals are, in general, bad practise as they are hard to keep track of and more likely to be overwritten by accident (e.g. in a race condition).
If you were using strict mode this would create an error instead of a global.
You are using all variables of yours as global variables. So all are recognized everywhere. In order to have a better understanding of variable scopes in Javascript have a look at this great example https://stackoverflow.com/a/500459/655316
I have something similar to this
function testfunction(runthis)
{
runthis();
}
function main()
{
var z = 15;
testfunction(function(){ alert(z); });
}
However it doesn't think z is in the same scope as my inline function. Without adding additional parameters to testfunction or my inline function, is there any way for my inline function to belong to the same scope as main? I'm trying to make callback functions work.
Edit: the above I imagine is a crappy example because it seems to be working. However the instance here http://pastebin.com/A1pq8dJR does not work unless I add .call(this,parameters) and manually set the scope (although I'm not exactly sure what this is doing). I would have thought this used there would refer to the scope imageLoaded has, but it is referring to the scope of imageBoxCreate? Could anyone explain why it wont work without that and why doing this fixed it?
If you just invoke a global function in javascript, the this object will be the top level window global object. If you invoke a function using the dot operator on an object, then this will be that object when the function runs. When you use function.call, you are explicitly specifying which object should be this. I think you are likely just making some scope mistakes with how you use this and var, but your code is long enough and involved enough that I'm not going to spend the time to debug it for you. If you can isolate you issue with a smaller code sample, folks should be able to help more easily.
lets say that I have the following scenario:
var namespace = {};
(function($)
{
$.extend(namespace,
{
test1: function(someArray, someObj)
{
for(var i= 0, ii= someArray.length;i<ii;i++)
{
var text = someObj[someArray[i]];
// do something with text
}
},
test2: function(someArray, someObj,i,ii,text)
/*
see that the i,ii,text are unused parameters,
that will be used instead of variables
*/
{
for(i= 0, ii= someArray.length;i<ii;i++)
{
text = someObj[someArray[i]];
// do something with text
}
},
});
})(jQuery);
Now, the result of the test1 and test2 are the same... but what about the performance, memory usage...
Is there any difference between declaring the i,ii, test variables in the two ways presented above ?
I think that the test2, for example, is probably more efficient because the variables are in the local function scope so after the function exits, the execution context is destroy, releasing the resources used for the arguments... the variables will not be assigned to the global object 'window'.
So what method is performing best? and why?
[Edit]
Thanks all for your answers !
There is no problem if the code has readability issues... I`m only interested now about the performance/memory usage.
If you do not declare your variables with var i then they become implicitly global.
Always declare your variables. If you did any benchmarking on that you would find that declared local variables are actually faster then implied global variables. Also you don't leak to the global state that way.
Benchmark!.
As you can see the performance is identical.
In terms of memory usage, local variables (test1) are probably better as the compiler doesn't have to remember that the function has 5 parameters.
But that's a nano optimisation If you care about performance differences of this caliber write assembly instead. Go for readable and maintanable code.
[Edit]
Didn't notice "local" variables in method parameter. That is a readability killer! Don't do that. You will find that test1 is probably still more efficient.
Why don't you profile your code?
The variables are also local in test1. You are declaring them with var i.
There is no difference between these methods.
The variables in "test1" are all declared with var, so they're not global. Those two should be essentially the same.
test1 is faster, because every time JavaScript looks for symbols (such as a variable name) it starts by looking in the local scope. So by using global scope it has to look in more places to find the symbols. The same applies for parameters, but they are better than globals.
It may be miniscule, but declaring a new variable (text) in every iteration would require new memory allocation I believe. Though I'm not sure how javascript handles that. I usually declare variables beforehand and then assign values afterwards for that reason, but that is only because someone said "hey you should do it that way" and presented the same argument.
A local function in the closure declares a variable with the same name which exists in the closure. So, how could we access closure's variable from the local function?
function closure()
{
var xVar;
function func1()
{
var xVar;
// how to distinguish local and closure scopes.
return xVar;
}
return function () { return func1(); };
}
Creating a private object and making private variables as properties of this object could help. But I am wondering if there is a better and neat solution. Can a scope chain help?
I have edited to make it a complete closure. Anyway, closures are not much concern here, it could be considered for inner functions however, there may be a solution with closures somehow.
Thanks
You can't access the scope chain explicitly in JS. Your problem is the age-old one of variable shadowing, but it's that much more maddening because in JS, the scope chain is actually there at runtime, it's just not available for you to access.
You can play some tricks with rejiggering current scope if you use the hated with operator, but that (as well as arguments's caller/callee stuff) really just give you access to objects and functions with their properties. There's no way to say "give me what xVar means in the n-1 runtime scope from right here".
Variables defined in an inner scope hide variable declarations in an outer scope. The "better and neat solution" is not to reuse variable names that way.
In your example the xVar variable is not a closure, because you redefined its scope to each function. To use that variable as a closure continue to declare it with the var command in the closure() function and then do not declare it with the var function in the func1() function. Instead just use the variable immediately in func1().
There is not an easy way to test if a function is a closure or a local variable. You would have to perform some sort of flow control test and then analyze assignments, where assignments occur, and where assignments do not occur. Then you must compare those results. You could write a tool, in JavaScript, to perform that analysis upon a given input and write you a report as output.
Many thanks in advance. I'm working out of a schoolbook and they're using one function to call another which opens a window:
function rtest(){
content='dans window';
oneWindow=open("","Window 1","width=450,height=290");
newWindow(oneWindow);
}
function newWindow(x){
x.document.close();
x.document.open();
x.document.write(content);
x.document.close();
x.moveTo(20,20);
x.focus();
}
So everything works fine, but my question is this: how is the newWindow() function able to access the contents of the "contents" variable in the rtest() function? And why, if I preface the "content" variable with "var", like this:
function rtest(){
**var content='dans window';**
oneWindow=open("","OneWindow","width=450,height=290");
newWindow(oneWindow);
}
...does an error get thrown (and the contents of the new window left blank)?
Can anybody explain to me what the difference between using var and not using var is?
Thank you!
Daniel
if you dont use var inside the rtest, it is automatically a global variable. which is why it is accessible from other javascript codes including newWindow. now, when you use var, it automatically a variable inside the rtest scope, so the ones that can use it now are those inside the same scope.
If you declare the variable using var inside the original function, it will become a local variable and will not be visible outside the function.
If you don't declare the variable at all, it will be global. However, best practice is to declare global variables. If your textbook doesn't do this, consider replacing it. If your professor doesn't do this, consider replacing (or reforming) him. :-) If you have trouble convincing him, you can (but not necessarily should) mention that I'm one of the top 200 users here.
For example:
var content;
function rtest(){
content='dans window';
oneWindow=open("","Window 1","width=450,height=290");
newWindow(oneWindow);
}
Also, the best way to open a blank window is to call open("about:blank", ...), not open("", ...).
It's about the function-scope, if you declare your variable with var, it will be available only in the scope of the function where you did it.
If you don't use the var statement, and you make an assignment to an undeclared identifier (an undeclared assignment), the variable will be added as a property of the Global object.
If you don't use var, then you are creating a global variable; that is, a variable that is accessible from any code anywhere in your program. If you use var, you are creating a local variable, which is a variable that is only accessible from within the scope in which it is defined (generally, the function it is defined in).
While global variables can be convenient at first, it's generally a bad idea to use them. The problem is that all of your code will share that one global variable; in the future, if you need to have two or more different versions of that variable for whatever reason, you won't be able to separate the two uses. Global variables can also be accessed or changed from anywhere within your program, so it can be hard to figure out what might be modifying or depending on one, while local variables can only be accessed within a limited, well defined section in code, which can easily be inspected.
With var you declare a local variable in the function which is thus not visible outside this function. Without var you are actually working on the window object and set or overwrite a field of it. Your global scope in client side Javascript is always the window object. So you could also have written window.content='dans window'; to make clearer what you are actually doing there, but otherwise it would be identical. By the way: the window variable is itself just a field of the window object that refers recursively back to the window.