Is it bad to use window property to create variables? - javascript

(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.

Related

Why can't I use certain variable names in javascript?

While coding I realized that certain variable names such as top, self, left\right create all sorts of errors when you try to use them. What's the reason behind this in JavaScript, while other languages can use them?
You can't use them as global variables because there already exist global accessor properties with these names.
top is used to access the top frame.
self is used to access the global object.
As far as I know there is no problem with left and right.
console.log(Object.getOwnPropertyDescriptor(window, 'top'));
console.log(Object.getOwnPropertyDescriptor(window, 'self'));
Attempting to assign some value to these variables will run the setter, which may not do what you expected. If there is only a getter but no setter, the assignment will be ignored in sloppy mode and throw in strict mode.
There is no problem in using these names as local variables. You should not use global variables anyways.
(function() {
var top = 123; // local variable
console.log(top === 123); // true - no problem
})();
var top = 456; // global variable
console.log(top === 456); // false !!!
There are no problems using variables with those names in JavaScript in most cases.
In some environments, some of the names are already used for existing global variables and are read only.
top is one such example, it refers to the top level frame.
You can still use it as the name of a variable in a non-global context.
Most probably you use variables without declaring them with var/let, and in such circumstances, you modify properties of the global execution environment.
In browser, the global execution environment is window, so when you do
self = '...'
you effectively do
window.self = '...'
self, top, left, right are properties of window object which may have certain non-standard behaviors. Many built-in properties of window object are in fact implicit setters which do more than setting a variable - they can also modify the current page, navigate etc. Also, many built-in properties of window can not be overridden, so assigning to them has no effect.
Contrary, when you do
(function() {
var self = '...'
})()
you should not have any problems.
You need a function call to make it work properly, to create a new scope, because in global scope, even with var, you'd still implicitly assign a property to window.

Chrome console: difference between 'let' and 'var'?

I've attached an animated gif to illustrate this weird behavior. Essentially, my question is does Chrome console treat var and let differently when used in the same scope? You'll notice that after declaring / assigning a variable, if you try to type that variable's name into the console, Chrome will autocomplete it for you, showing a dropdown list containing what your typing. When using lets, this is not the case. Is this a bug, feature, or is there something I'm missing about var and let in JavaScript?
Note: I'm well aware that let lives & dies within the immediate scope.
When you use var in the console, it executes in the global scope and adds the variable to the window object.
When you use let in the console, it executes in the global scope, which doesn't add the variable to the window object.
When you start typing, autocomplete checks the parent object for properties to complete along with other language constructs, such as function, for, and while.
When there is no content in the console, the parent object is window, which won't have the property you're looking for because let doesn't add the property to window.
As soon as you have a new object for autocomplete to complete, behavior returns to what you'd expect.
> let foo = {bar: 'baz'};
> foo.b //autocompletes bar
Now, with all of that said, there's no reason that autocomplete has to behave that way. In many regards the lack of autocomplete for variables defined in global scope via let could be considered a "bug" worth "fixing". In my opinion it is moderately surprising behavior.
var defines a variable on the global scope, while let defines it only in the local scope. Most likely, the autocomplete is only looking on the global scope for targets.

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).

Is 'window' always on top of the scope chain in javascript?

I've seen global variables defined with window.global_name.
I wonder why not just using global_name even if this script will be run in closure.
UPD: seems like IE doesn't explicitly add it to the window object, when you declare it inside of a closure
The last object on the scope chain in any ECMAScript environment is always the global object. In browsers, window is to all intents and purposes the global object. If you want to access a property of the global object x or a global variable x (which are almost but not quite the same thing), you should explicitly qualify it with window.x to avoid the possibility of x being resolved as a property of another object on the scope chain, or globalObj.x if you care about portability to non-browser environments. You can get a reference to the global object from anywhere in ECMAScript 3 or non-strict ECMAScript 5 as follows:
var globalObj = (function() { return this; })();
window.x is safer than simply x if there might possibly be another x in the current or preceding scopes. That being said, even window isn't fool-proof because you could define a variable named window.
They have similar effects, but window lets you explicitly declare that you're deliberately using a global. Otherwise, the reader doesn't know whether it's a var further up the scope chain, you just forgot to declare it, etc.
Unless you introduce another scope, e.g. by wrapping your code in a function, window === this === <the global scope>
However, window and this have the advantage that you can use the array syntax (window['something']) so you can access globals even if you have their name only in a string without using evil things like eval.
The answer is yes. If you declare a variable without the var keyword (inside a function), the variable will become implicitely a member of the window object, that is automatically initialized by the browser.
Outside a function, with or without the var keyword, the variable becomes implicitely a member of the window object.

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

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.

Categories

Resources