В какой момент прототип Object родился в JavaScript? - PullRequest
1 голос
/ 29 октября 2011

Допустим, у меня есть функция конструктора:

function Cat()
{
  this.tail = "long";
  this.colour = "black";
}

console.log(Cat.prototype); 
// returns an empty [object Object] with no properties (checked with `for...in` loop).

Так что на данный момент Cat.prototype не имеет tail и colour.

var Charlie = new Cat();
console.log(Charlie.tail);

Так как же Charlie наследует свойства Cat, если они не определены в его прототипе. Я предполагал, что весь смысл объекта-прототипа состоит в том, чтобы отражать или хранить свойства конструктора, которые будут наследоваться всеми экземплярами cat - это неправильно?

В какой момент объект-прототип заполняется этими свойствами? Или это происходит только тогда, когда я в качестве примера явно указываю Cat.prototype.eyes = brown?

Кроме того, каков правильный подход для запроса свойств прототипа Объекта? Это for...in петля? Я думаю, это не может быть Object.getOwnPropertyNames(Cat.prototype), потому что это не вернет унаследованные свойства.

Ответы [ 5 ]

2 голосов
/ 29 октября 2011

Вы определяете свойства tail и colour непосредственно в экземпляре.Эти свойства не определены для объекта prototype.

Кстати, каждая функция имеет свойство prototype и создается в момент создания самой функции.

1 голос
/ 29 октября 2011

Прототипы в Javascript немного отличаются от того, что вы описываете.В этом случае Charlie имеет хвост, потому что Charie IS Cat, то есть он является экземпляром Cat класса Cat.В вашей функции Cat вы добавляете свойство tail всем кошкам с помощью строки this.tail =.Это происходит полностью потому, что вы вызвали функцию Cat с ключевым словом new.Когда вы делаете это, javascript создает новый объект, а затем заставляет this указывать на этот объект в контексте функции.

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

Charlie.tickle_wiskers();

Javascript будет искать функцию с именем tickle_wiskers в объекте Чарли.Если он не найдет эту функцию, он будет выглядеть в прототипе Charlies (который по умолчанию равен Object.prototype, если вы не установили его явно).Наконец, я мог бы дать всем котам эту функцию, выполнив следующее:

Cat.prototype.tickle_wiskers = function() { 
      alert('meow');
    }
1 голос
/ 29 октября 2011

prototype полностью отделен от this.

Все вещи в this не наследуются, вещи в prototype будут.По умолчанию вы наследуете от Object.prototype (который пуст)

function Cat()
{
  this.tail = "long";
  this.colour = "black";
}
Cat.prototype.getColour = function () {
  return this.colour;
}

WhiteCat.prototype = Cat.prototype;
WhiteCat.prototype.constructor = WhiteCat;

function WhiteCat(name){
  Cat.call(this);
  this.colour = "white";
}    

var c = new Cat();
console.log(c.getColour()); // "black"
var w = new WhiteCat();
console.log(w.getColour()); // "white"
0 голосов
/ 29 октября 2011

Кроме того, каков правильный подход для запроса свойств прототипа Объекта?

var myProto = Object.getPrototypeOf(someObject);
var names = Object.getOwnPropertyNames(myProto);
names.forEach(function (name) {
  value = myProto[name];
  ...
});

Или это происходит только тогда, когда я явно устанавливаю Cat.prototype.глаза = карие в качестве примера?

Да, свойства [[Prototype]] объекта устанавливаются только тогда, когда вы устанавливаете их вручную.

Но так как каждый "экземпляр" объектаПрототип имеет живой указатель на объект-прототип, эти изменения будут отражаться после создания объекта.

хранит свойства конструктора, которые будут унаследованы всеми экземплярами cat - это неправильно?

Мы не храним свойства объектов в прототипе.Мы храним свойства (в основном методы), которые хотим использовать среди всех экземпляров прототипа / конструктора.

0 голосов
/ 29 октября 2011

Прототип никогда не получит свойства, которые вы положили в объект.У объекта есть члены прототипа, но у прототипа нет членов объекта.

Объект не наследует ничего от прототипа, члены в прототипе все еще существуют только в прототипе, они доступны только с объекта.Если вы удалите что-то из прототипа после создания объекта, этот член также больше не будет доступен из объекта.

Функция имеет свойство prototype, и когда вы используете ключевое слово new для вызовафункция как конструктор, созданный объект получает прототип из функции.

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

function Cat() {}

var c = new Cat();

Cat.prototype.test = function() {
    alert('test');
};

c.test(); // alerts 'test'
...