Кто-нибудь может объяснить, почему Javascript из этих слайдов не работает?

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?" );
}
1
Casebash 27 Авг 2010 в 05:40

4 ответа

Лучший ответ

Эта ссылка все еще поддерживается:

var samurai = { yell: ninja.yell };

Так что этот вызов .yell() в порядке, однако этот не так:

return n > 0 ? ninja.yell(n-1) + "a" : "hiy";

Этот вызов фактически ссылается на ninja, который теперь null, а null.yell() не является функцией :)

Вот измененная версия, которая показывает проблему.

3
Nick Craver 27 Авг 2010 в 01:45

Samurai.yell является «копией» функции из ninja. В этой функции он ссылался на ninja, которого больше не было, когда Samurai.yell был выполнен .

1
Cristian Sanchez 27 Авг 2010 в 01:45

Вы написали ninja = null перед вызовом функции.
Функции Javascript захватывают внешние переменные по ссылке, поэтому идентификатор ninja внутри функции ссылается на значение current переменной.

2
SLaks 27 Авг 2010 в 01:42

В рекурсивном вызове функции используется ссылка на ninja внутри yell (), и когда вы устанавливаете для нее значение null, он больше не может вызывать ninja.yell, потому что ninja имеет значение null.

Изменить:

return n > 0 ? ninja.yell(n-1) + "a" : "hiy";

Кому:

return n > 0 ? this.yell(n-1) + "a" : "hiy";

И это работает.

4
chubbsondubs 27 Авг 2010 в 01:49