2013-02-26 4 views
2

У меня есть следующий код Javascript;Смущает поведение прототипа Javascript

var Person = function(name, age) { 
    this.name = name; 
    this.age = age; 
    return this; 
}; 

Person.prototype.getAge = function() { 
    alert("Age : " + this.age); 
} 

var p1 = new Person("xyz",10); 
p1.getAge(); 

Это отлично работает, и я получаю предупреждение, как Возраст: 10

Теперь, если я обновлю код, как показано ниже (определяется СеЬАд() после того, как инстанцировании Person объект p1);

var Person = function(name, age) { 
    this.name = name; 
    this.age = age; 
    return this; 
}; 

var p1 = new Person("xyz",10); 

Person.prototype.getAge = function() { 
    alert("Age : " + this.age); 
} 

p1.getAge(); 

Он по-прежнему возвращает мне результат, как «Возраст: 10»

Теперь мой вопрос, как это работает правильно, так как Person.prototype.getAge была определена после того, как мы создали экземпляр объекта Person p1? Это из-за того, как работает «прототип»?

ответ

1

Объекты в JavaScript имеют вид цепи, где, если вы спросите их имущества, они вернутся них и, если у них нет, он будет пытаться найти его над своей цепи, в вашем случае, когда p1 запрашивает его свойство getAge, он ищет его в Person.prototype.

var Person = function(name, age) { 
    this.name = name; 
    this.age = age; 
    return this; 
}; 

var p1 = new Person("xyz", 10); 
var p2 = new Person("abc", 12); 

Person.prototype.getAge = function() { 
    alert("Age : " + this.age); 
} 
p1.getAge = function() { 
    alert("I am " + this.age + " years old."); 
} 

p1.getAge(); // I am 10 years old. 
p2.getAge(); // Age : 12 

В this example, p1 имеет свое собственное свойство СеЬАда, поэтому, когда его спросили, он возвращает его. С другой стороны, p2 действительно не обладает этим свойством, но может получить к нему доступ через «эту цепочку» и возвращает свойство своего прототипа.

1

Да, так работает прототип. Вы можете использовать эту технику для расширения строк, объектов и массивов.

1

Любой прототип объекта может быть изменен в любое время. Подумайте о библиотеках/рамках, которые модифицируют базовые Object прототип ... даже встроенные в объектах (Date, String и т.д.) будет иметь модификации сделаны для Object.prototype ли не произойдут, они сразу же при загрузке страницы

попробовать это :

Object.prototype.myTest = function() { console.log('hi'); } 
var a = new Date() 
a.myTest(); //hi 
+1

Я был готов к повышению, но, пожалуйста, сначала не расширяйте 'Object.prototype', который полностью не рекомендуется, если вы действительно не знаете, что вы делаете ... – MaxArt

+0

@MaxArt Я могу изменить что, например, _ «Не расширять« Object.prototype' ** с перечислимым свойством **, если вы на самом деле не имеете в виду его. Обычно настраиваемые методы должны ** не перечислимы **, и поэтому должны быть определены с помощью ['Object .defineProperty() '] (https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/defineProperty)." _ – Phrogz

+0

@MaxArt: Я не рекомендую расширять 'Object. прототип "- хорошая идея, просто как пример для OP, демонстрирующий, что прототип может быть изменен в любое время – BLSully

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