JavaScript: как получить доступ к прототипу функции конструктора? - PullRequest
0 голосов
/ 28 октября 2011

Может быть, глупый вопрос к гуру JS и ниндзя, но здесь идет речь:

Мое понимание прототипа объекта / свойства объекта состоит в том, что это план будущих экземпляров объекта.Учитывая это, не должен ли вновь созданный экземпляр объекта быть идентичным объекту конструктора, который его создал?

var x = new Object(); 
console.log(x === Object.prototype); // returns false. why?? 

* ОБНОВЛЕНИЕ *

Так что понимание того, чтоэто вернет false, потому что они ссылаются на разные вещи, я все еще нахожу, что новые Object () и Object.prototype содержат различное количество свойств.Итак, чтобы уточнить мой вопрос: как правильно проверить количество свойств в прототипе Object;как мне их перебрать?

Причина, по которой меня это смутило, заключается в том, что если я создаю простую функцию конструктора:

function Circle(){
   this.tail = "yes, has tail";
}

и хочу получить количество свойств,делать что-то вроде:

console.log(Object.getOwnPropertyNames(Circle.prototype)); 
// returns "constructor", I expected it to return "tail"

Ответы [ 4 ]

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

=== не отвечает на вопрос, эквивалентны ли две вещи, но являются ли они ссылками на один и тот же объект.

x и Object.prototype в вашем примере могут иметь одинаковые свойства, поэтому вы можете назвать их эквивалентными, но это два разных объекта.

Если вы делаете

x.foo = 3

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

Если

x === Object.prototype

были правдой, тогда

x.foo === Object.prototype.foo

будет одинаковым независимо от того, что вы присваиваете x.foo или Object.prototype.foo.

EDIT:

function Circle(){ this.tail = "yes, has tail"; }

console.log(Object.getOwnPropertyNames(Circle.prototype)); 
// returns "constructor", I expected it to return "tail"

На Circle.prototype нет свойства tail, потому что вы никогда не делали Circle.prototype.tail = ...;. Вы определяете tail только для Circle экземпляров через this.tail = ...;.

Я все еще нахожу, что new Object() и Object.prototype содержат различное количество свойств.

Вы также делаете getOwnPropertyNames. собственные свойства - это те, которые не унаследованы от прототипа, поэтому при использовании этой функции в x вы явно исключаете все свойства Object.prototype.

Документы для hasOwnProperty довольно хорошо объясняют "собственную собственность":

Этот метод можно использовать для определения, имеет ли объект указанное свойство как прямое свойство этого объекта; в отличие от оператора in, этот метод не проверяет цепочку прототипов объекта.

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

console.log(Object.getPrototypeOf(x) === Object.prototype); // true

Если вы хотите получить скрытое свойство [[Prototype]], которое указывает на следующий элемент в цепочке прототипов для объекта, просто вызовите Object.getPrototypeOf.

Также вынеправильно понимать, как работает цепочка прототипов.

Для любого данного объекта, если вы посмотрите на свойство, оно сначала будет смотреть на этот объект.Затем он будет (рекурсивно) проверять значение [[Prototype]] объектов на предмет наличия этого свойства.

Пример цепочки прототипов:

var o = new Object();
// o -> Object.prototype -> null
var a = new Array();
// a -> Array.prototype -> Object.prototype -> null
var Super = function () {};
var Child = function () {};
Child.prototype = Object.create(Super.prototype);
var c = new Child();
// c -> Child.prototype -> Super.prototype -> Object.prototype -> null
0 голосов
/ 29 октября 2011

По поводу вашего обновления:

this внутри функции конструктора - это экземпляр, созданный с ключевым словом new, а не prototype.

Итак, в случае с вашим фрагментом ...

function Circle(){
   this.tail = "yes, has tail";
}

Настройка this.tail аналогична:

var c = new Circle();
c.tail = "yes, has tail";

tail является только свойством экземпляра.

Чтобы установить tail на prototype, вы должны использовать:

Circle.prototype.tail = "yes, has tail";

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

function Circle() {
    // give the instance its "own" `foo` property
    this.foo = 'qux';
}

Circle.prototype.foo = 'foo';
Circle.prototype.bar = 'bar';

var c = new Circle();

console.log(c.foo); // the overridden "qux", not the inherited "foo"
console.log(c.bar); // "bar", as inherited

// yet the prototype still persists to have its "own" `foo`
console.log(Circle.prototype.foo); // "foo"

// While the instance has keys for all involved properties
console.log(Object.keys(c)); // [ "foo", "bar" ]

// It also retains which are its "own"
console.log(Object.getOwnPropertyNames(c)); // [ "foo" ]
0 голосов
/ 28 октября 2011

x является экземпляром объекта. Возможно, вы захотите проверить, есть ли у x Object как конструктор. Прототип не конструктор. Попробуйте это

var x = new Object(); 
console.log(x.constructor === Object);
...