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