var ninja = {
yell: function(n){
return n > 0 ? ninja.yell(n-1) + "a" : "hiy";
}
};
console.log(ninja.yell(4) == "hiyaaaa");
var samurai = { yell: ninja.yell };
var ninja = null;
samurai.yell(4);
var ninja = {
yell: function yell(n){
return n > 0 ? yell(n-1) + "a" : "hiy";
}
};
console.log( ninja.yell(4) == "hiyaaaa");
var samurai = { yell: ninja.yell };
var ninja = null;
console.log( samurai.yell(4) == "hiyaaaa");
问题描述错误,已修改,直接来代码。第一段代码会出错,第二段代码可以执行,为什么呢,第二段代码给匿名函数一个名称了
从前,有一间房子,长这个样子:
里面的
func
是一把椅子。你分配给了它一个门牌号,叫
obj1
,于是你可以通过obj1.func
找到这把椅子。有一天,你又建了一栋房子,叫
obj2
,里面也有把椅子,叫func
。它和obj1.func
长得一模一样,因为它们就是指向同一把椅子。又有一天,你把
obj1
的门牌号丢了(obj1 = null;
)。然而通过obj2.func
,你仍然能访问`obj1`里的那把椅子。
为什么呢?
因为房子并没有丢啊,丢的只是门牌号而已。
Update
这又有所不同了,因为你在
ninja.yell
中递归调用了ninja.yell
,而ninja
已经被你赋值为null
了,自然访问不到。正确打开方式:
此为匿名函数递归正解
代码段1
代码1处 为对象ninja设置一个属性yell指向一个匿名函数表达式,并在匿名函数内部递归调用ninja.yell方法
代码2处 递归调用成功 输出true,递归执行ninja.yell
代码3处 新定义一个对象samurai,设置其属性yell指向ninja的yell属性,注意此时samurai的yell属性将指向一个函数对象,和其原来附着的对象ninja没有关系了,
要理解这一点,可以尝试运行下面的代码
代码4处 将ninja指向为null,那么ninja对象将在某个时刻被JS虚拟机GC掉
代码5处 执行时,JS引擎找到的ninja对象为null了,就会报错了
TypeError: Cannot read property 'yell' of null
,执行不下去代码段2
代码1处 为对象ninja设置一个属性yell指向一个有名字函数表达式,并在函数内部递归调用自己,注意这里的名字yell和ninjia的yell属性是2个不同的值哦
作为函数名字的yell只在自己定义的函数体内有效,能被访问到。之外的任何地方都不能被访问
代码2处 调用ninja.yell,在函数体内递归调用自己
代码3处 行为同代码段A
代码4处 将ninja指向为null
代码5处 执行时,因为递归不依赖于调用的对象,故其能正常运行
我们把代码调整下做个来测试一下