Why I can not delete global varaible in JS? - javascript

Using Chrome I passed in console this name of global variable:
multiConfig
And get result:
multi: {type: "1", containerId: "mp", go: {…}}
__proto__: Object
I try to delete this variable by click:
if (window['multiConfig']) {
delete window['multiConfig'];
}
And I get this error:
ERROR TypeError: Cannot delete property 'multiConfig' of [object Window]
Why?

You cannot delete a window variable, but you can unset it:
window['multiConfig'] = undefined;
Reason:
The window object is not configurable.
You can refer to this - How to unset a JavaScript variable?

Variables declared with var are added as properties on the global window object and cannot be deleted with the delete operator.
From MDN - var:
In the global context, a variable declared using var is added as a
non-configurable property of the global object. This means its
property descriptor cannot be changed and it cannot be deleted using
delete.
Reason for this is also explained:
The property created on the global object for global variables, is set
to be non-configurable because the identifier is to be treated as a
variable, rather than a straightforward property of the global object.
JavaScript has automatic memory management, and it would make no sense
to be able to use the delete operator on a global variable.
Also note that trying to delete a property set on of global window object for variables declared with var fails silently in non-strict mode and throws a TypeError in strict-mode.
Also note that you can delete a property from the window object if is set explicitly.
var a = 1; // can't be deleted
window.b = 2; // can be deleted
delete window.a;
delete window.b;
console.log(window.a);
console.log(window.b);

Related

Global variable created by function invocation holds empty string by default,should be undefined

If a variable is declared but not initialized , it will print undefined in the console.But in this particular case if i console.log(this.name) inside Person function it should create a global variable called name whenever i invoke the function .But the global variable must be undefined, instead it is holding a empty string .I even checked the window object .It has a property called name which holds empty string.Why it is behaving this way ?
function Person(){
console.log(this.name)
}
Person() // should prints undefined ,but prints empty string
That code doesn't create any global variable (other than Person, which is a kind of variable), it just tries to use one. But if you run it in a browser in the default loose mode, you see a string because browsers have a predefined name global: It's the name of the window in which the code is running. (If you ran it in strict mode, you'd get an error because this would be undefined during the call.)
If you run that not on a browser, or with a different name (one that isn't already a global), you'll see undefined.
There already exists a property name on the global object (window in the browser) which is an empty string, otherwise the value would certainly be undefined.

why can't global variables be deleted?

How come a properly declared global variable can't be deleted?
I don't know if this is across all program languages, but I know that in JavaScript it can't be deleted.
Source: Javascript the Definitive Guide O'Reilly.
When you use global variables and you want to be able to delete them, you should easily define them in a global object, without using var in your statement, like:
let's say you want to define a global varible in your code, and you need to be able to delete them whenever you want, so if you do:
function myfunc(){
var name = "Robert";
console.log(delete name);
}
and call it in your console you would have, false as the result of delete statement, which means it has not got deleted, but if you do it like:
function myfunc(){
var obj = {};
obj.name = "Robert";
console.log(delete obj.name);
}
then your result would be true, which means it gets deleted now.
now for global object if you create it like:
window.myobj = {};
then you can delete it and it actually get deleted:
delete window.myobj;
or
delete window["myobj"];
The thing is when you create your variable using var, in the window context, although it is on object in the window, but it doesn't get deleted, for instance if you do:
var myobj = {};
in the browser dev console, it gets defined in the window, and you can have it like:
window.myobj
but you can not delete it, because you have defined it in a var statement.
But do not forget to set it to null, if you really want it to get deleted from memory:
window["myobj"] = null;
delete window["myobj"];
As was stated in this answer by user Eric Leschinski
Delete a variable in JavaScript:
Summary:
The reason you are having trouble deleting your variable in JavaScript
is because JavaScript won't let you. You can't delete anything created
by the var command unless we pull a rabbit out our bag of tricks.
The delete command is only for object's properties which were not
created with var.
JavaScript will let you delete a variable created with var under the
following conditions:
You are using a javascript interpreter or commandline.
You are using eval and you create and delete your var inside there.
or you can set null to an variable which will behave like a deleted object
When variable is created in global scope then automatically DontDelete property is added to the variable and set to the true. That is the reason global variables (or functions too) can not be deleted.
For other variables that property is false so those can be deleted.
For more clarity you can refer the article : understanding delete
With ECMAscript 5, the properties added to an object now have attributes which allow you more control over the object. These attributes are:
value - The actual value of the property
writable - If the property can/cannot be changed.
configurable - If set to false,any attempts to change its attributes will fail in strict mode (and will return false in non-strict mode)
enumerable - if the property can be iterated over when the user does for (var prop in obj) {}
These attributes can be checked with another API exposed by Ecmascript 5 called:
Object.getOwnPropertyDescriptor(obj, prop)
Now, when you create a global variable WITHOUT the 'var' keyword, like so:
sum = function (a, b) { return a + b; }
then this property 'sum' get created on the window object with configurable attribute set to true.
console.log(Object.getOwnPropertyDescriptor(window, "sum"))
... and therefore this property CAN be deleted from the window object.
delete window.sum //returns true
But when you create a property with the var keyword, then configurable property is set to false like so:
var multiply = function (a, b) { return a * b; }
console.log(Object.getOwnPropertyDescriptor(window, "multiply"))
... and now, this property CANNOT be deleted.
delete window.multiply //returns false in non-strict mode
Courtesy: John Resig

Javascript context confusion

I have this object:
var test = {
setup: function() { property = 'hello!'; console.log(this); }
};
When I run test.setup(); and print out test.property(); it gives me undefined. I understand it's because I need to do this.property but my question is: why?
I can clearly see that the context is the test object via console.log(this), but for some reason it doesn't work.
Thanks
When JavaScript finds a loose assignment like property = 'hello!', it will create a global variable (or raise an error, if in strict mode). So if you want it to be a property, you have to be explicit.
Because in this situation, property = 'hello!' is the same as window.property = 'hello!', not this.property = 'hello!'.
If you assign to an undeclared variable, it will create a global variable.
When you declare variable with "no var" you will "accidentally" create global variable (attached to window object) so rule of thumb: Always use "var" with variable declaration.
With "var" here, you will create local variable to setup function.

Effect of declared and undeclared variables

What is the major difference between JavaScript declared and undeclared variables, since
the delete operator doesn't work on declared variables?
var y = 43; // declares a new variable
x = 42;
delete x; // returns true (x is a property of the global object and can be deleted)
delete y; // returns false (delete doesn't affect variable names)
Why does this happen? Variables declared globally are also the properties of the window object, so why can't it be deleted?
Declared and undeclared global variables
The mechanism for storing and accessing them is the same, but JavaScript treats them differently in some cases based on the value of the configurable attribute (described below). In regular usage, they should behave the same.
Both exist in the global object
Below are some comparisons of declared and undeclared global variables.
var declared = 1; // Explicit global variable (new variable)
undeclared = 1; // Implicit global variable (property of default global object)
window.hasOwnProperty('declared') // true
window.hasOwnProperty('undeclared') // true
window.propertyIsEnumerable('declared') // true
window.propertyIsEnumerable('undeclared') // true
window.declared // 1
window.undeclared // 1
window.declared = 2;
window.undeclared = 2;
declared // 2
undeclared // 2
delete declared // false
delete undeclared // true
delete undeclared // true (same result if delete it again)
delete window.declared // false
delete window.undeclared // true (same result if delete it yet again)
delete window.undeclared // true (still true)
Both declared and undeclared global variables are properties of the window object (the default global object). Neither one is inherited from a different object through the prototype chain. They both exist directly in the window object (since window.hasOwnProperty returns true for both).
The configurable attribute
For declared global variables, the configurable attribute is false. For undeclared global variables, it's true. The value of the configurable attribute can be retrieved using the getOwnPropertyDescriptor method, as shown below.
var declared = 1;
undeclared = 1;
(Object.getOwnPropertyDescriptor(window, 'declared')).configurable // false
(Object.getOwnPropertyDescriptor(window, 'undeclared')).configurable // true
If the configurable attribute of a property is true, the attributes of the property can be changed using the defineProperty method, and the property can be deleted using the delete operator. Otherwise, the attributes cannot be changed, and the property cannot be deleted in this manner.
In non-strict mode, the delete operator returns true if the property is configurable, and returns false if it's non-configurable.
Summary
Declared global variable
Is a property of the default global object (window)
The property attributes cannot be changed.
Cannot be deleted using the delete operator
Undeclared global variable
Is a property of the default global object (window)
The property attributes can be changed.
Can be deleted using the delete operator
See also
delete operator
Object.defineProperty
Object.getOwnPropertyDescriptor
hasOwnProperty
Strict mode
The main difference is when you're declaring variables inside a function. If you use var when you're declaring a variable inside a function, then that variable becomes a local variable. However, if you don't use var, then the variable becomes a global variable no matter where you declare it (inside or outside a function).
When any variable is created via Variable Declaration in JavaScript , these properties are created with "DontDelete" attribute , which basically means that variable you created cannot be Deleted using "delete" expression. All the functions, arguments , function parameters by default are created with this DontDelete attribute. You can think of DontDelete as a flag.
var y = 43;
delete y; //returns false because it is has a DontDelete attribute
Whereas Undeclared assignment doesn't set any attributes like DontDelete . So when we apply delete operator on this undeclared variable , it returns true.
x = 42;
delete x; //returns true because it doesn't have a DontDelete attribute
The difference between property assignment and variable declaration — latter one sets DontDelete, whereas former one doesn’t. That's why undeclared assignment creates a deletable property.
Link on how exactly delete operator works
delete is only effective on an object's properties. It has no effect on variable or function names.
In your case x = 42; declares variable X and makes it the property of the Global object. So it returns true.
And var y = 43; declares a global variable which is not part of any object so it returns false.

The global object is an object of which class?

I want to know what the global object in JavaScript is and to which class this object belongs to.
And how are Infinity, NaN and undefined part of the global object?
Variable scope is defined in JavaScript by a function, and functions can be nested inside other functions.
function foo() {
// new variable scope in here
var a = "a";
function bar() {
// another nested variable scope
var b = "b";
}
bar();
}
foo();
EXCEPT there is a default "global" variable scope that is defined when your program runs. It is the base variable scope in which all function created scopes are nested.
So what?
Well, every variable scope has a variable object (or more accurately, a "binding" object). It's an internal object to which all the local variables you create are bound.
This variable object is not directly accessible. You can only add properties to it by declaring a local variable (or function parameter, or function declaration). And you can only access properties via the variable names.
Again, so what?
Well the "global" variable scope is unique. It exposes this internal variable object by automatically defining a property on the object that refers back to the object itself. In a browser, the property is named window.
Because a property is placed on the object that refers back to the object, and because properties on the object become variables, we now have a direct access to the global variable object.
You can test this by observing that the window.window property is an equal reference to the window variable.
alert(window.window === window); // true
As a result, we can add a property to the object window.foo = "bar";, and it show up as a global variable alert(foo); // "bar".
Note that the only variable scope that exposes this internal object is the global scope. None of the function scopes expose it.
Also note that the ECMAScript specification does not require that the global variable object be exposed. It is up to the implementation to decide.
There are no real classes, but if you mean the prototype chain of the global object, the specification doesn't say much:
The values of the [[Prototype]] and [[Class]] internal properties of the global object are implementation-dependent.
([[Class]] is used in e.g. window.toString() so that you may get "[object global]".)
The three values you mention are properties of the global object, e.g.:
Infinity === window.Infinity; // true (in a browser the global object is window)
You cannot overwrite these variables, so you can see them as literals. But in reality they are properties of the global object, and thus you can refer to them as variables ("global variables").

Categories