深入了解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 = {}
)来擦除了该对象,但在第二个示例中,您通过分配了null
(ninja = null
)来实现了此目的。没关系,在两个示例中使用空白对象或null
都会得到相同的结果(尽管您在第二个示例中收到的错误会更改)。旁注2:请注意,每个示例中的第二行
var ninja = ...
实际上都被视为ninja = ...
。构造var x = y;
实际上是在不同时间发生的两个完全不相关的事物:变量声明var x
,它在进入包含它的执行上下文(松散地称为“作用域”)时发生;以及x = y;
赋值操作,该操作在逐步执行中到达该行代码时发生。一个作用域内有多个声明是没有操作的。更多:Poor misunderstood var