I was reading Secrets of the JavaScript Ninja and came across a coding example:
var ninja = {
yell: function(n){
return n > 0 ? ninja.yell(n-1) + "a" : "hiy";
}
};
var samurai = { yell: ninja.yell };
//var ninja = {};
//delete ninja;
samurai.yell(4);
If I uncomment the second commented line, samurai.yell(4)
runs fine, I understand it as samurai
still has its reference to the function originally referenced by ninja.yell
, which delete
removed.
However, if I run the first commented line instead, samurai.yell(4)
will give an error.
Can someone explain what's happening under the hood?
I thought if you assign ninja
to be undefined
, a new reference will be created and linked to ninja
, the original reference is still there, and since samurai
still has a reference to the function, garbage collection won't come along and delete it in memory.
When you write
var ninja = {
yell: function(n){
return n > 0 ? ninja.yell(n-1) + "a" : "hiy";
}
};
var samurai = { yell: ninja.yell };
var ninja = {};
//delete ninja;
samurai.yell(4);
var ninja = {};
will declare a variable named ninja
the next line samurai.yell(4);
will throw an error since ninja has been re-defined and the new object does not have any function named yell
associated with it.
Explanation :
In the beginning, ninja
is
var ninja = {
yell: function(n){
return n > 0 ? ninja.yell(n-1) + "a" : "hiy";
}
};
Here ninja has a function yell
inside it which can be called.
When you change it's value to
ninja = {};
The old value ( along with the function ) gets erased and overwritten with the new value.
Therefore, when you call
samurai.yell(4);
It goes to { yell: ninja.yell };
and since the new ninja
doesn't have yell
function, it throws an error
As I said in comments, it's all about how closures work:
var bar = 1;
var foo = function() { console.log(bar); } // closes over `bar`
foo(); // closed-over `bar` reference: 1
bar = 2;
foo(); // closed-over `bar` reference reflects the update: 2
delete bar;
foo(); // closed-over `bar` still references the same location,
// even when current context no longer has it
You don't often see examples with delete
, but it is this very mechanism that makes them useful as a replacement for private variables:
var foo = (function() {
var bar = 1;
return function() {
console.log(bar);
};
})();
foo(); // closed-over `bar`: 1 - even though:
console.log(bar); // Uncaught ReferenceError, as
// `bar` is not available in local context
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With