2015-12-07 3 views
1

Я пытался найти код ниже.prototype javascript confusion

function Foo(who){ 
     this.me = who; 
} 
Foo.prototype.identify = function(){ 
    return "I am " + this.me; 
}; 
var a1 = new Foo("a1"); 
a1.identify(); 
a1.identify = function(){ 
    alert("Hello, " + Foo.prototype.identify.call(this)); 
}; 
a1.identify(); 

Над кодом работает хорошо, и я понимаю, почему использовался Foo.prototype.identify.call. Я хотел проверить свое понимание этого, поэтому я изменил a1.identify ниже

a1.identify2 = function(){ 
    alert("Hello, " + a1.identify()); 
}; 
a1.identify2(); 

Я ожидал, что выше, чтобы работать таким же образом. Теперь я просто ссылаюсь на идентификацию по прямой цепочке протоколов. Однако, когда я бегу выше, я получаю неопределенное значение. Я что-то упустил (или не понял?).

+0

Я думаю, что вы не вызываете функцию u r только для печати функции. Это должно быть «alert» («Hello,» + a1.identify()); вместо «alert» («Hello,» + a1.identify); –

+2

Непонятно, каков ваш вопрос на самом деле. В коде, который у вас выше, нет ничего неопределенного. Вы можете увидеть результаты здесь: http://jsfiddle.net/jfriend00/94yLngj6/. Вероятно, вы хотели написать «alert» («Hello», «+ a1.identify());« фактически запустить 'a1.identify()», чтобы не распечатывать сама функцию, но когда я запускаю то, что вы указали выше в jsFiddle, ничего не отображается как 'undefined'. – jfriend00

+0

Благодарим вас за быстрый ответ. Да, это потому, что у меня не было a1.identify() в предупреждении ИЛИ не вызывается a1.identify2()() .. спасибо, что заставило меня осознать это !!! Спасибо вам за быстрый ответ. hmmm, также, я запускал это в хром-инструментах для разработчиков и возвращал мне неопределенное значение, когда я запускал код, как я представил в оригинальном сообщении. – user3502374

ответ

1

Я не могу сказать, в чем ваш вопрос. Когда я запускаю код in a jsFiddle, в нем нет ничего undefined. Вы делаете alert() на a1.identify, а не a1.identify(), так что вы фактически не вызывали функцию, и я предполагаю, что это была ваша ошибка. Вместо этого a1.identify просто попытается сделать преобразование .toString() в методе, который попытается сбросить источник функции (это то, что показывает мой jsFiddle или ваш код).

Так что, возможно, вы имели в виду, чтобы сделать это:

a1.identify2 = function(){ 
    alert("Hello, " + a1.identify()); 
    //   parens added here ^^ 
}; 
a1.identify2(); 

Возможно, что вам, возможно, потребуется объяснил, что эти два могут быть несколько разные вещи:

Foo.prototype.identify 

и

a1.identify 

Если ничего не было присваивается непосредственно a1.identify, тогда выполнение a1.identify() не найдет объект .identify непосредственно на объекте a1, поэтому он будет выглядеть на Foo.prototype и он найдет там свое имя и выполнит его на прототипе.

Но, как только вы сделаете это:

a1.identify = function() {...} 

Тогда у Вас есть "перекрываться" это свойство. Теперь, когда вы делаете:

a1.identify() 

интерпретатор JS находит свой перекрываться свойство непосредственно на a1 объекта и выполняется вместо свойства, которая находится на прототипе.Когда вы делаете obj.property, интерпретатор JS сначала смотрит на это свойство непосредственно на объект, и только если он не найден, назначенный непосредственно объекту, он выполняет поиск прототипа объекта для свойства с этим именем.

Как вы, кажется, знаете, вы всегда можете получить функцию, которая находится на прототипе, даже если имущество было перекрываться непосредственно на объекте, перейдя непосредственно через прототип с:

Foo.prototype.identify.call(a1) 

Итак, вы можете переопределить свойство prototype для определенного экземпляра, и даже если вы его переопределили, вы можете получить исходное свойство прототипа, если вам нужно или хотите.

+0

Благодарим вас за подробное объяснение. Принято! – user3502374

1
a1.identify2 = function(){ 
alert("Hello, " + a1.identify()); 
}; 
a1.identify2(); 

a1.identify() должны были названы с ().

a1.identify() вызывает alert() и не возвращает никаких значений. В этом случае возвращается неопределенный. Таким образом, когда a1.identify2() звонков a1.identify(), a1.identify() выполнен и не определен. Следовательно, вы видите «Hello, undefined».

Если вы хотите увидеть выход в identify2(), то в identify1() вместо предупреждения, return значение.

+0

Благодарим за помощь! – user3502374