Javascript variables: Var a and window.a difference? - javascript

I try to understand why?
Variable a is not defined and i didn't assign any value to it.
however, if i call a, it returns exception, but a is a var of window object. If i call a like window.a it returns undefined.
below screenshot is.
why so?
screenshot

In first case there is no existence of a.
You have neither declared a.
So js have no idea of a. When ever you are trying to access a no existence variable it will throw a ReferenceError
In second case you are trying to find a property called a in the window object. window.a will check if there is any property a defined on window. If it is not it will return undefined

Related

Using "call" properly in Javascript to access object properties

I'm new to Javascript, and despite having read several threads and tutorials online, I can't correctly use "call" in this example to access the property of the object
I know the problem is that when "b ()" is called, "this" is the global object, and I have to use the call (or apply) method to make sure that when "b" is called this is set to the object itself, but I can't find the error.
I know that arrow functions exist, and that there may be other approaches, but I want to understand what is the matter with this using of call. Thank you.
The code is
class Letter {
constructor() {let a = "a";}
b() {alert (this.a);} //can't access a. Prints "undefined"
c() {this.b.call(this);}
}
let p = new Letter ();
p.c();
The a does not exist as a property of the object - it's a variable, an identifier visible within the constructor function, not an instance on an object.
There's no good way to gain access to a variable declared in another scope like that. For what you're trying to accomplish, define a as a property of the instance instead.
constructor() {
this.a = 'a';
}
You won't need .call at all - just do this.b().

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.

Undefined variable with & without object name in JS

When I run the following simple Javascript line...console logs an error.
console.log(abc);
But when I run the above line like
console.log(this.abc); or console.log(window.abc);
the console does not throw an error. Instead it prints "undefined".
Why?
Note: 'abc' variable is not defined or declared.
It's not errornous to refer to a non-existent property, but it is erronous to refer to a standalone variable name which doesn't exist.
When one references a non-existent property on an object, undefined will be returned - that's how how things work. But standalone variable names, on the other hand, do need to be defined before referring to them, in almost all situations. Failing to define a standalone variable before trying to refer to it will throw a ReferenceError in all but 2 situations:
(1) When using typeof
console.log(typeof foo);
(2) When assigning to such a variable in non-strict mode (the variable will be implicitly created on the global object):
const arr = [1, 2, 3];
for (i = 0; i < arr.length; i++) {
// if in sloppy mode, and i hasn't been defined beforehand,
// it will be created as a global variable
}
console.log(typeof i);
If you try to assign to such a variable in strict mode when it hasn't been declared beforehand, an error will be thrown.
When you looking for a variable
console.log(abc);
Is not defined and should throw
Uncaught ReferenceError: abc
is not defined in any context at all
however
console.log(this.abc) and console.log(window.abc)
part of it is defined
console.log(this)
console.log(window)
return current objects instance and window objects respectively and have a reference point. the plain console.log(abc) has no reference point
actually it's not a variable. It is a key which is inside an object. (At this point the object is this or window). this and window created from JavaScript.
It's an interesting question to ask!.
To be able to understand this, we must understand Variable Hoisting in Jaascript.
if you want an undefined for a variable that is not declared yet , well the following would work!
console.log(abc)
var abc = 'ss';
So, here if we try to access a declared variable before it is initialized then undefined is actually assigned at the top of function execution. in other words, all the variables are hoisted to the top of their immediate scope level and are assigned undefined until they reach the initialization point.
to give you a blunt answer, trying to use an undeclared variable would give you Reference Error while trying to access a declared variable before the initialization would give youundefined
and, for objects like this and window well they are available objects . so basically at this point people say, In Javascript everything is present, meaning, trying to access a property that is not yet there in a js object would give you undefined.
On most browsers and Javascript environments that respect Javascript specification (this may change in other javascript environments where there is no console):
Any property that has not been assigned a value or non existent property (or a function without a return statement) returns undefined.
In the first examples, the dot operator is being called. The behaviour in case you access a non existent property is defined and it is that to return undefined, which is a valid js type. Therefore undefined is being logged.
On the last example, on the other hand, the non existent variable throws a ReferenceError. This happens directly, as unlike the first case, no context has been accessed, no dot operator is being called and this is just a plain error.
It is the normal JavaScript behavior.
Lets consider a variable name
var name;
console.log(name);
The above wont throw an error, because the variable name was declared before using it in console.log.
console.log(name);
This will throw a reference error because you did not declare the variable first.
But,
If name is accessed from an already defined variable( e.g. window, this ), it wont throw an error whether defined or not. Just like the below will simply print undefined, reference error wont be thrown.
console.log(window.name);
Note that window is already defined by the browser.
Notwithstanding,
console.log(window_a.name);
the above will throw a reference error because name is being accessed on an undefined variable window_a.
var window_a = {};
console.log(window_a.name);
This wont throw reference error because window_a is now declared.

ReferenceError and the global object

In JavaScript in the browser window is the global object, which means every variable defined in the global scope is a child of window. So why do I get this result:
console.log(window.foo); // No error, logs "undefined".
console.log(foo); // Uncaught ReferenceError: foo is not defined.
Fiddle
Those two lines should be the same, shouldn't they?
Because with window.foo you are explicitly looking for foo property of window object which is not the case in latter option. In the latter option, if foo isn't defined, you should as developer be able to know that it isn't defined and get the clear error warning rather than interpreter setting it to undefined on its own (like first case) which will lead to unexpected results.
Reference Error:
Represents an error when a non-existent variable is referenced.
A ReferenceError is thrown when trying to dereference a variable that has not been declared.
Take a look at this article for more info:
Understanding JavaScript’s ‘undefined’
Quoting from above article:
A Reference is considered unresolvable if its base value is undefined. Therefore a property reference is unresolvable if the value before the dot is undefined. The following example would throw a ReferenceError but it doesn’t because TypeError gets there first. This is because the base value of a property is subject to CheckObjectCoercible (ECMA 5 9.10 via 11.2.1) which throws a TypeError when trying to convert Undefined type to an Object.
Examples:
var foo;
foo.bar; //TypeError (base value, foo, is undefined)
bar.baz; //ReferenceError (bar is unersolvable)
undefined.foo; //TypeError (base value is undefined)
References which are neither properties or variables are by definition unresolvable and will throw a ReferenceError, So:
foo; //ReferenceError
In your first example (window.foo) you are accessing a property of the window object. JavaScript returns "undefined" for when you are trying to access a non existent property of a object. It's designed that way.
In the second example you are referencing a variable directly, and since it does not exists an error is raised.
It's just the way JavaScript is designed and works.
In JavaScript you can assign object fields on the fly like that, so window.foo is nearly (see comments below) equivalent to var foo; when defined in the global context, whereas just calling foo out of the blue makes the browser panic 'cause it down't even know which object to look in. Notice, if you do:
//when in global context, 'var' sets a property on the window object
var foo;
console.log(foo);
//it will then also log `undefined` instead of throwing the error.
//if you then do:
foo = "abbazabba";
console.log(window.foo);
// it will return "abbazabba"

How to distinguish between a variable that is not declared and a varrable that is declared but not be assigned any value?

Both scenario, the typeof the variable will be "undefined".
But undeclared variable will raise a exception.
Is there a easy way to handle this?
You may find the question (and my answer) in How to check if a variable or object is undefined? relevant. In general, I view any access to an "undeclared variable" a programming error.
However, this particular case can *only** be detected with the use of detecting for a ReferenceError exception. But, yuck, yuck, yuck! Remember variable declarations are a static lexical construct, ignoring the quirks with property-variables of the global object.
ReferenceError, and now "strict", exist for a reason and I suspect this is an X-Y problem. I do not even recommend the use of typeof for this purpose: fix the code :-)
Happy coding.
*It has been pointed out that "variable" in window will also [and only] work for global "variables" (they are really just properties that don't need be qualified in all contexts).
if property we want to check in object whether that it exists or not, even if its undefined.
we will use one of these:
'prop' in obj(to check for properties from prototype chain) or
obj.hasOwnProperty('prop')
we need to use methods above to check if property exists as accessing property that has not been declared in object will also return undefined.
var o={};
o.c=undefined;
o.c===undefined; //is true
o.a===undefined; //is true as well even though c exists while a doesn't
commonly not a problem as nobody really declare undefined properties much, but when do so do it like this.
o.c=''; //when it can be string or
o.c=null; //to clearly indicate that its nothing.
then
o.c === undefined will return false!
note!!!
null == undefined //true while
null === undefined //false that's why use three equals to test
For variables not declared and are not inside object. When accessed The compiler will return (reference)error.
If it doesn't it means its being treated as a global property, window object property, and was not declared, at least in all parent scope, so it will be undefined just as o.a was at top. it will become window.prop.
so x; //error
but x=3; //no error assumed to be global object.
just like o.abcd = 3; would...
make(declare) a property abcd in object o valued(assigned) 3 all at once.
To avoid properties to become a global variable we use var keyword inside function, like this var k;
One thing you can do about this catch the reference error when throw for a variable that doesn't exist and are thought to be a variable itself.
try {
x
} catch(e){//code to run when x is not declared let alone defined.}
You can try:
var a;
try {
a;
alert('a');
} catch(e) { /* a not defined */ }
try {
b;
alert('b');
} catch(e) { /* b not defined */ }
alert('done');
DEMO
You should never be attempting to access undeclared vars if you're writing clean JS. To avoid such pitfalls (among many others) start LINTing your JS with http://www.jslint.com/ or http://jshint.com/ .
A good read to help you understand the LINT tools and reasoning behind their findings is Crockford's Book, JavaScript: The Good Parts ( http://www.amazon.com/gp/aw/d/0596517742 ).

Categories

Resources