var ninja = {
chirp: function signal(n) {
return n > 1 ? signal(n - 1) + "-chirp" : "chirp";
}
};
assert(ninja.chirp(3) == "chirp-chirp-chirp", "Works as we would expect it to!");
var samurai = { chirp: ninja.chirp };
ninja = {};
assert(samurai.chirp(3) == "chirp-chirp-chirp","The method correctly calls itself.");
将此与
进行比较var ninja = {
chirp: function(n) {
return n > 1 ? signal(n - 1) + "-chirp" : "chirp";
}
};
assert(ninja.chirp(3) == "chirp-chirp-chirp", "does not work");
var samurai = { chirp: ninja.chirp };
ninja = {};
assert(samurai.chirp(3) == "chirp-chirp-chirp","The method cannot reference function.");
在将samurai
对象重新定义为chirp
之后,ninja
如何引用ninja
对象中的ninja = {};
属性?
答案 0 :(得分:0)
引用函数或对象的变量实质上是指向存储位置的指针。重新分配变量后,它指向的内存位置中的任何内容都不会更改-只是一旦脚本中的 anywhere 不再引用该对象,该对象最终将被垃圾回收。
因此,ninja = {}
不会更改ninja
原来是的对象。由于samurai
引用了ninja.chirp
,因此ninja.chirp
函数将不会被垃圾回收-或至少直到samurai
仍然存在时才会被垃圾回收。
chirp
或signal
函数可以用signal(n - 1)
进行调用,因为它是一个命名函数-命名为signal
,因此可以引用并使用其函数名称进行调用。匿名函数没有名称,因此它们不能像这样引用自己。
答案 1 :(得分:0)
功能可以独立于对象而存在,反之亦然。将signal
函数和ninja.chirp
属性视为两个独立的实体,两者都位于程序存储器中。 ninja.chirp
只是指向signal
的指针。将samurai.chirp
分配给ninja.chirp
时,您正在创建另一个指向signal
函数的指针。销毁ninja.chirp
并不会销毁signal
,至少在没有其他对象引用的情况下销毁,在这种情况下,销毁samurai.chirp
。此外,只要匿名函数不是递归函数,它也适用于匿名函数,如下所示:
var ninja = {
chirp: function (n) {
return console.log("chirp "+n+" times!");
}
};
ninja.chirp(3);
var samurai = { chirp: ninja.chirp };
ninja = {};
samurai.chirp(3);
答案 2 :(得分:0)
chirp
对象的ninja
属性引用内存中某个位置的函数(名为signal
。)ninja
对象基本上对该对象具有“远程控制”功能。该“远程控制”被命名为chirp
。创建samurai
对象时,您创建了另一个引用了signal
函数的“远程控件”。
只要有“远程控件”指向该函数,该函数仍将存在于内存中。