JavaScript variable scope question: to var, or not to var - javascript

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.

Related

Is it bad to use window property to create variables?

(Sorry for my poor English)
I finally realized why it's better to use let or const instead of var because var can't work with window properties!
However, is it a good idea still to use window properties as variable names just because you can bypass the problem by using other two keywords of creating variables?
For example:
var name = 'James';
console.log(name);
The above won't work because I'm using var keyword however if I used let or const, this wouldn't cause any error!
So once again, just because I can should I ?
Using variable names that exist as properties on the window object was never the real problem. Using them for global variables was (and still is). But if you are in a local scope, e.g. inside a function, you can name your local variables however you like.
If you cannot avoid global variables, you should strife to use as few as possible, and yes you should try to avoid collisions with other globals, be they properties of window or not. Using let or const just ensures that if they are window properties, your custom variable will shadow them, but you will still break other code that relies on these to be accessible as global variables with the builtin value. However, most of the time you cannot avoid global variables you also cannot avoid var, as let and const cannot be redeclared.
var
Function-scoped variable. It is visible in the current function. If it's outside all functions, then it's visible globally, assuming it's not in module scope.
let
Block-scoped variable. It's visible in the {} block where it was defined.
const
Block-scoped constant. Like let, it's block-scoped, but this one is constant.
object property
window is an object, so let's think about objects in general.
window.foo = "bar"; console.log(window.foo);
"Better"
One is not "better" than the other by definition. You will need to think about your needs and the conventions your team has agreed upon and apply them. Setting window attributes should not be a custom in general, because you are making it global, but sometimes you need to set window properties. Again: always think about what you need to achieve.

Properties vs variables - Javascript

Can anyone tell me the difference between these? I started noticing some behaviours that i was not expecting.
let myObj = {  _name:"Consala",
get name(){
return `Mr. ${this._name}`  }}
Why does this require the this keyword because i thought functions have access to all variables surrounding them.
I explained this by saying that variables are different from properties and there is no variable called _name inside of the myObj just a property. Im not sure if this is correct though.
I tried to test this theory using this:
let test = "banana"
print(test) //prints banana
print(this.test) //prints undefined
this.test = "apple"
print(this.test) //prints apple
I thought this confirmed what i thought because when undefined was printed i explained it as there is no property called test on the global object showing me there is a difference between variables and properties.
But then i changed let to var and then print(this.test) also prints banana instead of undefined...
Whats going on here?
Im pretty confused but im thinking that when you use var you are setting a property to the object its in (which would explain why var has function scope right?) but then what happens when you use let?
**I hope people dont think of this as a low effort post because i have really been trying to figure this one out on my own rather than just refusing to think for myself. Cheers
The reason why var prints banana instead of undefined is because you have declared it outside of all functions so it takes global scope.
The scope of a variable declared with var is its current execution context and closures thereof, which is either the enclosing function and functions declared within it, or, for variables declared outside any function, global.
Reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/var
On the other hand, let is block scoped so it gives you undefined
And to answer your question about why we need this, it is because the name getter function has no variable called _name in its scope.
Thus it needs this to indicate to it to use the object scope to look for the _name variable
this keyword is the most confusing keyword in JavaScript. It's not because it's kind of buggy or what but it's because developers think it will work in the same way as it does in other languages but that's not true.
this has dynamic scope. Dynamic scoping does not care how the code is written, but instead how it executes. So the value of this depends on how is it executed.
Talking about your first example
let myObj = { _name:"Consala",
get name(){
return `Mr. ${this._name}` }}
In this case, when you call that function you type myObj.name which binds myObj as this to name. So whenever you call a function using [Object Name].[function] you assign this object as the function's this.
Let's come to the second scenario. I assume you tried that in your browser.
In the case of Browser, this refers to window Object (Try console.log(this) ).
What happens there is when you declare a variable using let it doesn't add to Window object but when you declare it using var keyword, it adds to Window Object.
Try declaring a Variable using var and then do console.log(this). You will find that variable in Window Object but in case of a variable declared using let won't be there.

Avoid declaring variables on scroll?

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

Javascript: is the Windows object a default object?

First time poster. I tried to search for answer before posting.
I'm new to javascript, coming from a Delphi/pascal background. I am used to things having to be explicitly spelled out. When I see code that includes setTimeout or setInterval (see here:
http://www.w3schools.com/js/tryit.asp?filename=tryjs_setinterval1), I notice that it just looks like an intrinsic function. But I think it is actually a method of the Windows object.
So it looks like the "window." part is optional. Is this somethign specific to the Window object? Or will any method that is specified without the name of it's containing object be recognized in javascript? And what would happen if there was another variable in the global scope that had a method also named setTimeout? How would the compiler/interpreter know which one to use?
Thanks so much,
Kevin
In Javascript, there is something called the Global scope. On Browsers, the global scope object is window. If you create a variable outside of a function, it goes by default into the global scope, which is window.
When invoking a method or referencing a variable on the window object, it's optional to include window.
its not windows its window (no 's' at end).
As far as i know javascript have 3 scopes local, [clouser], global
Every variable or function is first looked up in local scope, then clouser and finally if not found anywhere in between it will checked in global scope.
As in image you will see global scope is shown as Window object which mean whatever goes in global scope goes in window object.
copy paste below code in chrome devtools console
function outerFunction() {
var a = 10;
debugger;
function innerFunction() {
'use strict';
var b = 10;
debugger;
console.log(a);
}
innerFunction();
}
outerFunction();
on 1st debug
on 2nd debug

Re-defining global variable with conflicting local variable

So I was trying to get a handle on JavaScript's scope and looking up lots of info about it. I saw a lot of questions about people accidentally making local variables that conflicted with global ones.
But I was wondering if there was a way to change global variables despite a conflicting local variable.
Like:
var globalVariable = 6;
var func1 = function() {
this.func2 = function() {
var globalVariable = 99;
= 7;
}
};
print(globalVariable);
Is there a way to change the global variable value despite that conflicting local variable name?
When I tried this.globalVariable = 7 to print 7 as the output, it did not work. Can anyone make clear why the this.access did not work or if there is even a way to change the global variable if there does happen to be a local of conflicting name?
Obviously it would not make sense to write code this way, but I thought I understood that the this. keyword always specified the global variable/object?
"I thought I understood that the this. keyword always specified the global variable/object?"
No. The value of this depends on how a function is called and whether the function is in strict mode.
In the browser global variables are properties of the window object, so use:
window.globalVariable = 7;
Sometimes this is equal to window, but often it is not. (I don't mean that to sound like this just gets set randomly; there is a specific set of rules that apply.)
Note that if you find yourself needing to distinguish between global variables and local variables like this you might well be using too many global variables.
You could use window['globalVariable'] = 7;
It's not a good solution though. There really are none.
The "this" variable refers to the scope the current function has, usually, unless it was bound to something else or called/applied (.call/.apply). I'd suggest Googling function scope because it can get quite confusing.
I'm on Skype if you have any more questions (thetenfold).

Categories

Resources