1

我们在挖掘 JavaScript 时遇到了麻烦,请帮助我们。提前致谢

下面的代码,为什么武士仍然不能调用函数叫喊

===>
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." );

但是在这些代码中它不能叫喊

===>
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?" ); 
}
4

1 回答 1

7

在第一个示例中,yell是一个命名函数。在函数中,符号yell解析为函数,因此它能够调用自身。ninja因此,您是否清除了该对象并不重要。

var ninja = { 
  yell: function yell(n){ 
  //             ^^^^-------------------------- the name
    return n > 0 ? yell(n-1) + "a" : "hiy"; 
  //               ^^^^------------------------ using the name
  } 
};

在第二个例子中,yell是一个匿名函数,它试图通过 调用自己,当被清除ninja.yell时显然失败了。ninja

var ninja = { 
  yell: function(n){ 
  //            ^-------------------------------------- no name
    return n > 0 ? ninja.yell(n-1) + "a" : "hiy"; 
  //               ^^^^^^^^^^-------------------------- relies on `ninja` object
  } 
}; 

旁注:在您的第一个示例中,您ninja通过为其分配一个不同的空白对象 ( ninja = {}) 来清除该对象,但在第二个示例中,您通过分配null( ninja = null) 来完成。没关系,使用空白对象或null在两个示例中会产生相同的结果(尽管您在第二个示例中收到的错误会改变)。


旁注 #2:请注意,var ninja = ...每个示例中的第二行实际上都被视为ninja = .... 该构造var x = y;实际上是两个在不同时间发生的完全不相关的事情: 变量声明 ,var x它在进入包含它的执行上下文(松散地,“范围”)时发生;和赋值操作,x = y;当在逐步执行中到达该行代码时发生。在一个范围内有多个声明是无操作的。更多:可怜的误解var

于 2013-10-25T11:34:24.250 回答