2014-03-15 4 views
1

У меня возникли трудности с пониманием, почему этот код не работает. Из того, что я могу сказать, мой синтаксис верен, но console.log жалуется, что у моего объекта person нет метода setFirstName. Вот что у меня до сих пор:У моего объекта нет метода?

HTML

<input type="text" id="firstName"> 

Jquery

$(document).ready(function() { 
    $("#firstName").on("change", getFirstName); 

    var person = new Person(); 

    function Person() { 
     this.firstName = ""; 
    } 

    Person.prototype = { 
     setFirstName: function(name) { 
      this.firstName = name; 
      console.log("My first name is: " + person.firstName); 
     } 
    } 

    function getFirstName() { 
     var firstName = $("#firstName").val(); 
     person.setFirstName(firstName); 
    } 
}); 

Строка кода журнала отображает консольных эту ошибку и указывает на "person.setFirstName (имя)" :

Uncaught TypeError: Object #<Person> has no method 'setFirstName' 

Меня озадачивает, что он распознает объект Person, но не видит меня thod setFirstName. Что я сделал не так? Помогите мне, мастерские кодеры, вы - моя единственная надежда.

ответ

3

Текущий код присваивает литерал объекта прототипу Person. Вместо этого, назначить функцию к setFirstName свойству Person.prototype:

Person.prototype.setFirstName = function(name) { 
     this.firstName = name; 
     console.log("My first name is: " + this.firstName); 
} 

Объяснение

Чтобы понять эту ошибку, мы должны сначала понять, как prototype сек работа в JavaScript. Когда экземпляр объекта создается с использованием конструктора функций, прототипу экземпляра присваивается прототип функции-конструктора.

function MyObject(){} 
var myObj = new MyObject(); 
console.log(myObj.__proto__ == MyObject.prototype); //logs true 

В представленной кода, экземпляр Person создается с помощью функции Person конструктора. Это вызывает назначение person прототипу Person.

var person = new Person(); 
function Person() { 
    this.firstName = ""; 
} 
console.log(person.__proto__); //logs Person{} 

Тогда объект литерал, содержащий функцию setFirstName присваивается прототип Person.

Person.prototype = { 
    setFirstName: function(name) { 
     this.firstName = name; 
     console.log("My first name is: " + person.firstName); 
    } 
} 

На данный момент Person прототипа, присвоенный объект буквального с функцией, однако экземпляр person был создан до объекта буквального был назначен прототипом Person «s. Прототип экземпляра person не относится к литералу объекта, который был присвоен Person.prototype после его создания.

console.log(person.__proto__ == Person.prototype); //logs false 

Хотя не рекомендуется, мы могли бы решить или избежать этой проблемы путем создания экземпляра person после того, как новый прототип был назначен, например:

$(document).ready(function() { 
    $("#firstName").on("change", getFirstName); 

    function Person() { 
     this.firstName = ""; 
    } 

    Person.prototype = { 
     setFirstName: function(name) { 
      this.firstName = name; 
      console.log("My first name is: " + person.firstName); 
     } 
    } 

    var person = new Person(); 
    function getFirstName() { 
     var firstName = $("#firstName").val(); 
     person.setFirstName(firstName); 
    } 
}); 

Это гораздо лучше назначить метод свойство Person.prototype, так что мы не создаем временную связь, которая диктует, когда может быть создан экземпляр Person.

Это article делает отличную работу по разъяснению prototype и стоит прочитать.

+0

Разве это не мой путь для этого? – Frijolie

+0

Нет, вы заменяете прототип литералом объекта, который вы создаете. –

+0

Исправлена ​​ошибка. Спасибо, что поймали его. Изменил его на ваше предложение, и он работает. Благодаря! – Frijolie

Смежные вопросы