Сообщение от JSprog
|
Как сделать то чтобы выводился не строковый вариант функции а результат?
|
Ну я ж говорю - вызвать её - поставить скобки вызова:
alert(a.getX()); // 10
alert(b.getX()); // 20
Сообщение от JSprog
|
И есть ли у экземпляра объекта свойство prototype
|
Надо подвести итог и собрать воедино то, что мы тут наобсуждали.
1. Есть конструкторы и есть объекты, порождаемые от этих конструкторов:
function A(x) { // конструктор
this.x = x;
}
var a = new A(10); // объект "а", порождаемый конструктором А
var b = new B(20); // объект "b", порождаемый конструктором А
Здесь "А" - конструктор, "а" и "b" - порождаемые от "А" объекты. Внутри конструктора this указывает на создаваемый объект, поэтому "а" и "b" имеют свойство "x".
2. Если создавать свойства и методы в конструкторе, они получаются
свои для каждого объекта, что влечёт за собой больший расход памяти:
function A(x) {
this.x = x;
this.getX = function () {};
}
var a = new A(10);
var b = new B(20);
alert(a.hasOwnProperty('x')) // true
alert(b.hasOwnProperty('x')) // true
alert(a.hasOwnProperty('getX')) // true
alert(b.hasOwnProperty('getX')) // true
3. Узнал, что у порождаемых объектов есть
прототип, в котором хранятся
общие для всех экземпляров свойства и методы. Поэтому, методы, поскольку они одинаковые, удобней хранить в прототипе:
function A(x) {
this.x = x;
}
A.prototype.getX = function () {};
var a = new A(10);
var b = new B(20);
alert(a.hasOwnProperty('x')) // true
alert(b.hasOwnProperty('x')) // true
alert(a.hasOwnProperty('getX')) // false!
alert(b.hasOwnProperty('getX')) // false!
// один и тот же метод
alert(a.getX == b.getX) // true
alert(a.getX === A.prototype.getX); // true
alert(b.getX === A.prototype.getX); // true
4. Узнал, что конструктор и ссылка конструктора .prototype связаны с порождаемым объектом лишь на этапе создания. Дальше, этот конструктор и ссылка .prototype могут быть об
null'ены, но порождённый объект всё равно будет иметь связь с прототипом - посредством
внутренней неявной (скрытой) ссылки объекта на прототип. Эта ссылка называется [[Prototype]]. В браузере Firefox, её можно получить через .__proto__ (это я уже сам прочитал
):
function A(x) {
this.x = x;
}
A.prototype.getX = function () {};
var a = new A(10);
var b = new B(20);
alert(A.prototype.getX === a.__proto__.getX); // true, вот она, настоящая ссылка на прототип
alert(A.prototype.getX === b.__proto__.getX); // true, и здесь
// поэтому, мы можем присвоить null
A.prototype = null;
A = null;
// но всё равно достучаться до метода .getX из прототипа
// через .__proto__
alert(a.getX()); // 10
alert(b.getX()); // 20
// Просто изначально, A.prototype и a.__proto__ и b.__proto__
// указывают на один и тот же объект:
// A.prototype ---> [Прототип] <-- a.__proto__ и <-- b.__proto__
При этом, явно __proto__ указывать не надо.
Это и есть наследование, основанное на прототипах: если свойство/метод не найдены в самом объекте, его поиск продолжается в прототипе. Т.е. метод .getX не найден в самом объекте "а", но будет найден в a.__proto__.getX (или, по стандарту a.[[Prototype]].getX). Аналогично с объектом "b".
5. Конструктор сам может хранить свои свойства (как в примере в начале темы):
function A(x) {
this.x = x; // свойство экземпляра
}
A.x = 100; // свойство конструктора
var a = new A(10);
alert(a.x);
alert(a.constructor.x); // 100
Поправь, если я где-то ошибся.