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.