It's important to look at the original unmodified source for this one:
1. | var ninja = {
2. | yell: function(n){
3. | return n > 0 ? ninja.yell(n-1) + "a" : "hiy";
4. | }
5. | };
6. | assert( ninja.yell(4) == "hiyaaaa", "A single object isn't too bad, either." );
7. |
8. | var samurai = { yell: ninja.yell };
9. | var ninja = null;
10. |
11. | try {
12. | samurai.yell(4);
13. | } catch(e){
14. | assert( false, "Uh, this isn't good! Where'd ninja.yell go?" );
15. | }
The change you made to change ninja.yell
to yell
is an invalid edit to the script.
What I don't understand is when the ninja object is set to an empty object, the yell method is still available to samurai.
It's important to understand how assignment works in JavaScript. JavaScript has a lot of convenient shorthand notations that can make things harder to understand when you're new to the language.
var samurai = { yell: ninja.yell };
Is a shorthand way of saying:
var samurai;
samurai = new Object();
samurai.yell = ninja.yell;
When samurai.yell = ninja.yell
is called, a reference to the ninja.yell
function is added to samurai
.
In JavaScript, functions are objects too. They are passed by reference. What samurai.yell = ninja.yell
does not do is copy any sort of reference to ninja
.
On line 9 of the example, var ninja = null
does not modify the function at ninja.yell
in any way. It also does not modify the object that was stored at ninja
in any way. What it does is remove the reference to the object that was stored at ninja
, and replace it with a value of null
. This means that any other copy of the object referenced at ninja
will still point to the object that was referenced at ninja.
It's easier to see with an example:
var foo,
bar;
foo = {
fizz: 'buzz'
};
bar = foo;
foo = null;
console.log(bar.fizz); //buzz
Is it because since there is still a reference lying around to ninja, it wasn't garbage collected?
After line 9 of the example script executes, there are no longer any references to the object that had been at ninja
. There is a reference to the function that had been at ninja.yell
. What this means is that the ninja
object can be garbage collected, but the ninja.yell
object (which happens to be a function) cannot.