Reputation: 1211
We've encountered a trouble when digging into JavaScript,Please help us. Thanks in advance
Below codes, why samurai still can't call function yell
===>
var ninja = {
yell: function yell(n){
return n > 0 ? yell(n-1) + "a" : "hiy";
}
};
assert( ninja.yell(4) == "hiyaaaa", "Works as we would expect it to!" );
var samurai = { yell: ninja.yell };
var ninja = {};
assert( samurai.yell(4) == "hiyaaaa", "The method correctly calls itself." );
But in these code it can't call yell
===>
var ninja = {
yell: function(n){
return n > 0 ? ninja.yell(n-1) + "a" : "hiy";
}
};
assert( ninja.yell(4) == "hiyaaaa", "A single object isn't too bad, either." );
var samurai = { yell: ninja.yell };
var ninja = null;
try {
samurai.yell(4);
} catch(e){
assert( false, "Uh, this isn't good! Where'd ninja.yell go?" );
}
Upvotes: 1
Views: 542
Reputation: 1074595
In the first example, yell
is a named function. Within the function, the symbol yell
resolves to the function, and so it's able to call itself. So it doesn't matter that you've wiped out the ninja
object.
var ninja = {
yell: function yell(n){
// ^^^^-------------------------- the name
return n > 0 ? yell(n-1) + "a" : "hiy";
// ^^^^------------------------ using the name
}
};
In the second example, yell
is an anonymous function and it tries to call itself via ninja.yell
, which obviously fails when ninja
has been wiped out.
var ninja = {
yell: function(n){
// ^-------------------------------------- no name
return n > 0 ? ninja.yell(n-1) + "a" : "hiy";
// ^^^^^^^^^^-------------------------- relies on `ninja` object
}
};
Side note: In your first example, you wipe out the ninja
object by assigning a different, blank object to it (ninja = {}
), but in the second example you do it by assigning null
(ninja = null
). It doesn't matter, using a blank object or null
would have the same result in both examples (although the error you receive in the second example would change).
Side note #2: Note that the second var ninja = ...
line in each example is actually treated just as ninja = ...
. The construct var x = y;
is actually two completely unrelated things that happen at different times: The variable declaration, var x
, which happens upon entry to the execution context (loosely, "scope") containing it; and an assignment operation, x = y;
, which happens when that line of code is reached in the step-by-step execution. Having multiple declarations within a scope is a no-op. More: Poor misunderstood var
Upvotes: 7