var sum = function(a, b) {return a + b;};
var add = sum;
delete sum;
After Executing Delete it return False in console. Ideally it should return True.
Why sum function is not deleted?
Note above code is executed in google chrome browser console.
From MDN:
The delete operator removes a given property from an object.
If the property which you are trying to delete does not exist, delete will not have any effect and will return true.
If a property with the same name exists on the object's prototype chain, then, after deletion, the object will use the property from the prototype chain (in other words, delete only has an effect on own properties).
Any property declared with var cannot be deleted from the global scope or from a function's scope.
As such, delete cannot delete any functions in the global scope (whether this is part from a function definition or a function expression).
Functions which are part of an object (apart from the global scope) can be deleted with delete.
Hence sum which is a function attached to the global scope, cannot be deleted with delete.
delete cannot delete with direct member .
The delete operator removes a property from an object.
Since you giving sum and not telling from which object you want to remove it.
What you looking for is
delete window.sum
Now it removes the sum from window object :)
demo
Refer MDN
The delete operator removes a property from an object.
Any property declared with var cannot be deleted from the global scope or from a function's scope.
As such, delete cannot delete any functions in the global scope (whether this is part from a function definition or a function expression).
Functions which are part of an object (apart from the global scope) can be deleted with delete.
Related
Can anybody please explain how variable value can exist after finish running the function?
I saw a code example of Higher order function but I don't understand how it keep track of variable in function after each run of the function.
in example below how variable count can add more after each run?
// Higher order functions
// A higher order function is any function that does at least one of the following
// 1. Accepts a function as an argument
// 2. Returns a new function
// Receives a function as an argument
const withCount = fn => {
let count = 0
// Returns a new function
return (...args) => {
console.log(`Call counts: ${++count}`)
return fn(...args)
}
}
const add = (x, y) => x + y
const countedAdd = withCount(add)
console.log(countedAdd(1, 2))
console.log(countedAdd(2, 2))
console.log(countedAdd(3, 2))
Note that the withCount function is called only once:
const countedAdd = withCount(add)
After that call, the variable count is created, and because they still have possible references in the same scope as it exists, it is not destroyed, making possible the use inside the scope.
Please note that the arrow function returned is inside the scope(function withCount).
What if¹ there would be no variables at all? What if there would only be a tree of, lets say objects? Each object has a list of key-value pairs, and a reference to its parent. Now how could we emulate variables with that tree? Well for global variables that is easy, we have to have some reference to the "global scope object" somehow, then we can add a key-value pair to that:
// var test = "value";
global.test = "value";
Now how do we represent a local scope? Quite easy: whenever a function gets called, we create a new such object, and let the parent reference point to the root object.
local.parent -> global
local.count = 0;
Now from that local function scope we can both look up local variables (count for example) and global ones, simply by traversing to the parent of the current scope and checking the variable there (test for example).
And for a function inside a function? Thats easy too: We just let the parent of the current scope object point to the one of the outer function:
local2.parent -> local
Now to look up count in that inner scope, we can go to the parent and find it as a property there.
Now the trick is, that those "context objects" do not disappear when the function ends execution, but rather when all references to it were lost.
Now we need another trick to make your example work:
A function declaration has to keep a reference to its parent scope, so when the function gets called, we can let the local scopes parent point to the parent scope.
Therefore if you do return (...args) => {, a reference will be kept to the "current scope object" (which contains count) and will be stored on the function. When you call it, the function will be executed with a new scope object, and that can access count through the parent reference. As long as you keep a reference to that function, the internal reference to that "scope object" will be kept, and that contains count.
¹ actually, this is exactly what happens. The ECMA spec calls these "scope objects" EnvironmentRecord ...
The thing you see here is called closure. You can find many good articles, books, explaining this concept. Basically, it's keeping an implicit reference to a variable.
The returned function below closes over variable `count`
return (...args) => ...
So when you call withCount, you retain a secret reference to count. And the other functions you called, just keep interacting with that variable.
Consider the below code,
function destroyer(obj){
obj = undefined;
}
abcObj = {
a:1,
b:2
}
destroyer(abcObj);
As far as I understand, all I can do is throw the object out of scope and the GC will clean it when it sees fit. But the above code does not throw the object out of scope.
How to force an object out of scope?
Reason for wanting to do so: The thing I wanted to achieve is a class having a static method destroy to destroy the instances of same class. Is that possible in javascript? Or is it that I can't force the cleanup. A cleanup method would be great since, the lib I'm working with spawns a lot of instances like 200 to 300.
You have to modify all the variables pointing to it.
abcObj = null;
You can't use a function to do it because that would copy the value to a new variable and leave the original untouched.
This is probably pointless as you are unlikely to be creating a significant number of objects without them falling out of scope naturally. 99.9% of the time you can just focus on writing code which does what you need it to do and let the JS engine worry about garbage collection in its own time.
Since it's defined globally just destroy it directly :
function destroyer(){
abcObj = undefined;
}
abcObj = {
a:1,
b:2
}
console.log(abcObj);
destroyer();
console.log(abcObj);
There is delete in JavaScript, but it does not delete objects, it deletes properties from objects. For your particular use case it could be used:
function destroyer(name){
delete window[name];
}
test="hello";
console.log(test);
console.log("before destroy");
destroyer('test');
console.log("after destroy");
console.log(test);
It works because you have a global variable, and "global" scope is actually "window" in the browser.
However in the general case the most you could do is to explicitly put your objects into some container object, and then you can remove them from there. It does not worth the effort IMHO.
EDIT: actually it does not work as a code snippet here, because it has its own "global-ish" scope, which is not window. But you can test it in the developer console of a browser.
EDIT2: I was wrong, it works here too, just I got confused because of the lengthy error message. Added log-lines before and after the destroyer-call.
You could pass your variable in an object, as a key, and pass that object to your destroyer function. That way, your function could use the object's first key to retrieve the global variable's name, and then delete it in the window object.
Please note this will only work for global variables.
// retrieves the first key of the object passed as parameter
function getFirstKeyName(someObject){
return Object.keys(someObject)[0];
}
// destroy a global variable by its name
function destroyGlobalVariable(withinAnObject){
// retrieve the variable's name
var globalVarName = getFirstKeyName(withinAnObject);
console.log("Deleting global variable " + globalVarName);
// use delete, assign undefined or null to window[globalVarName];
delete window[globalVarName];
}
abcObj = {
a:1,
b:2
}
// abcObj should be defined :
console.log(abcObj);
// pass your variable name into an object, as a key
destroyGlobalVariable({abcObj});
// abcObj should not be defined now :
console.log(abcObj);
Please consider the following snippet (fiddle here):
var a;
a = 1;
console.log(delete a); // prints 'false'
b = 1;
console.log(delete b); // prints 'true'
Why does the delete keywords behave differently on the global variables a and b?
From the MDN docs:
The delete operator removes a property from an object.
A global variable (without var) is a property on the global object (typically window), so can be deleted.
A var is not a global variable, but a local variable in the outer scope - not a property of the global object - so delete does not delete it. From those docs:
x = 42; // creates the property x on the global object
var y = 43; // declares a new variable, y
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)
MDN says delete returns false only if the property exists and cannot be deleted. It returns true in all other cases. After deleting, try testing the actual values. You'll see that a was not deleted. This is because, as the MDN page says, delete will not affect variable names.
It has no effect on variable or function names.
(i.e., defined with var and not off the global object)
Take a look at the examples on the following page.
https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/delete
From mozilla docs about var :
The difference is that a declared variable is a non-configurable property of the global object while an undeclared is configurable.
var a; --> This is a declared variable, because you are using var, so it's not configurable.
a = 6; --> This is an undeclared variable, because you are not using var, so it's configurable.
both syntaxes above will end up with a var named a attached as a property of the global object (window typically) and properties has these attributes:
Writable. If false, the value of the property can not be changed.
Configurable. If false, any attempts to delete the property or change its attributes (Writable, Configurable, or Enumerable) will fail.
Enumerable. If true, the property will be iterated over when a user does for (var prop in obj){} (or similar).
that is extracted from ecmascript5 objects and properties , and as you can read, the configurable attribute of the variable in question affects whether the variable can or cannot be deleted.
"var a" means it cannot be accessed from anywhere outside of the current block, thus deleting it WOULD mean UNDECLARE (not same as undefined), thus allowing to write "var a" again in the same block (error).
Allowed usages (MDN):
delete object.property
delete object['property']
delete object[index]
delete property
It's like GOTO and unstructured programming, where you might need to manually clean up resources, it's kind of ~Destructor in C (though not the same). You can delete an object like ~a(); but you cannot "'UNDECLARE' a variable" like "int i".
My question is dead simple.
I just casually discovered that once you have defined a property with this. into an object, you don't need to prepend this. anymore when you want to call them.
So this. is really meant to be used ad definition time, like var?
I found it my self shortly after, i was referencing the window object with this. since i called my object without using new, so like it was a function.
One extra question, maybe for comments. Inside the main object, if i create a new object, and use this during the object definition, this this what will be referring to?
No, unless the context of this is a global object, such as window. Take the following example:
function Foo(bar) {
this.data = bar;
console.log(this.data); // OK
console.log(data); // ReferenceError
}
In this example, you'll get a ReferenceError: data is not defined on the first console.log(data), unless, data is a global variable. To access the instance's public member, you have to use this.data.
References:
Understanding JavaScript’s this keyword
The this keyword
There are all sorts of circumstances where you MUST use this in order to reference the right data.
These two implementations do very different things:
Array.prototype.truncate(newLen) {
// sets the length property on the current Array object
this.length = newLen;
}
Array.prototype.truncate(newLen) {
// sets a global variable named length
length = newLen;
}
var arr = [1,2,3,4,5,6,7];
arr.truncate(2);
You MUST use this in order to control what happens if you want to modify the current object. Your assumption that you can leave it off and it will still modify the current object's properties is not correct. If you leave it off, you are modifying global variables, not member properties.
So this. is really meant to be used ad definition time, like var?
No, the point of this is to be the current scope of execution. You can (and will) run into weird errors if you don't use this. For example, imagine you are an object with a property val and then on the prototype of that object you have
App.obj = function(){
this.val = 'initial';
}
obj.prototype.myMethod = function(val) {
// how would you assign argument val to object val?
}
also note that your reasoning breaks down with methods.
obj.prototype.meth2 = function(){
myMethod(); // fails where this.myMethod() would work.
}
See http://jsfiddle.net/BRsqH/:
function f(){
this.public='hello!';
var hidden='TOP SECRET!';
}
var instance=new f();
alert('Public data: '+instance.public+ /* gives "hello!" */
'\nHidden data: '+instance.hidden /* gives undefined */
);
Variables created with var are hidden and cannot be viewed nor modified outside the function which created them.
But variables created with this are public, so you can access them outside the function.
I think I got it.
I defined my object as function My_Object(){...} and then called it with MyObject(). This way the My_Object was treated as a function, not an object and therefore this == window.
So in the end I was attaching properties and methods to window instead of My_Object! That's way there were available without prepending .this.
The right way to initialize My_Object as an object is to call it like this new My_Object, isn't right?
This is something that I'm sure I should know the answer to, but either I'm just being stupid or I've just somehow never come across this before...
Given the following array, declared in the global scope:
var arr = [function() {
console.dir(this);
}];
I would have expected this to refer to the Window object. However, when calling the function:
arr[0](); //Logs Array
It appears that this actually refers to the array. Then, when I store a reference to the function in another variable and call that, this does refer to the Window object:
var func = arr[0];
func(); //Logs Window
So, why does the context of the function change? Here's a fiddle demonstrating the above two cases.
When you call a function as property of an object, such as obj.func(), this refers to obj.
This is exactly what you are doing here. arr is your object and 0 is the property holding a function.
Note: After all, arrays are just objects and their elements are the values of their properties (though properties are typically numerical strings (all properties are strings)).
See MDN - this for more information, in this case:
When a function is called as a method of an object, its this is set to the object the method is called on.
In your second case, you call the function "standalone", hence this refers to window. If the code was run in strict mode though, this would be undefined.
This is because this keyword is actually an operator which returns the reference to the holder (or owner) of a function where it was called. Since in first case the holder is an array (which is an object) it returns an array. In the second case the holder is the window object.
See this article for more details.
be noted:
in JavaScript, this always refers to the function owner.
you can read more about it at quirksmode.
Because the element is a member of the array, and this always points to the owner object (unless you play with bind()/ call()/ apply() etc). If you're not part of an object, this will be the global object; which is window in the browser environment. The exception to this is if you're in strict mode, where this will be undefined.
What you're doing is effectively the same as:
var ar = {
'0' : function () {
console.dir(this);
}
}
ar[0]();
var func = ar[0];
func();
... which may make more sense conceptually.
http://jsfiddle.net/TVtwr/1/