nguyenngoc101
nguyenngoc101

Reputation: 1211

Allocate memory in JavaScript

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

Answers (1)

T.J. Crowder
T.J. Crowder

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

Related Questions