深入了解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?" );
}

最佳答案

在第一个示例中,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 = {})来擦除了该对象,但在第二个示例中,您通过分配了nullninja = null)来实现了此目的。没关系,在两个示例中使用空白对象或null都会得到相同的结果(尽管您在第二个示例中收到的错误会更改)。



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

10-06 05:03