Javascript: доступ к общедоступному методу прототипа не работает - PullRequest
1 голос
/ 16 ноября 2011

Я хочу создать простой класс в Javascript только с одной публичной функцией следующим образом:

function A(myTitle) { 
    var title = "";
    this.getTitle = function() {
        return title;
    };
    title = myTitle;
};

var anInstance = new A("first");
console.log("anInstance.getTitle(): '"+anInstance.getTitle()+"'"); 
// expecting to return "first"

Это работает как ожидалось.

Теперь я хочу добавить этот класс в качестве прототипа к новому классу, который включает в себя новую переменную заголовка, чтобы метод getTitle () возвращал значение переменной:

var myA = new Object();
myA.title ="second";
myA.prototype = anInstance;
console.log("myA.getTitle(): '"+myA.getTitle()+"'"); 
// expecting to return "second"

Но вместо ожидаемой «секунды» это приводит к следующей ошибке:

TypeError: 'undefined' is not a function (evaluating 'myA.getTitle()')

В чем проблема с доступом к этой функции?

Обновление: Ключевым моментом для моего вопроса является следующее: в моем приложении я создам несколько тысяч экземпляров типа «А» и еще несколько других сопоставимых типов. Таким образом, эффективность и производительность памяти имеют значение. Поэтому я подумал, что было бы здорово создать соответствующие методы (еще несколько последуют, getTitle - только один пример) только один раз, и «объекты данных» ссылаются на эти методы. Это возможно?

Ответы [ 2 ]

2 голосов
/ 16 ноября 2011

Если все, что вам нужно, это переменные экземпляра (и это все, что я вижу, вы используете), что не так с идиоматическим JavaScript:

function A(title) { 
    this.title = title;
};

A.prototype.getTitle = function() {
    return this.title;
};

var anInstance = new A("first");
var myA = new A("second");

Вы можете реализовать как самоподобный прототип OO, так и Smalltalk-подобный OO на основе классов поверх JavaScript, но это имеет смысл только в случае иерархий наследования, где плоская модель JS (которая предпочитает композицию над наследованием - это Легко добавить новые методы в прототип или произвольные функции конструктора apply(), но вам придется перепрыгивать через некоторые обручи, чтобы наследование работало должным образом) недостаточно.

Относительно того, почему ваш код не может работать: ваш метод getTitle() возвращает лексическую переменную вместо переменной экземпляра, которая не принимает участия в разрешении свойств через цепочку прототипов и, следовательно, не может быть перезаписана по-вашему; также, .prototype - это свойство функций конструктора, которое используется для инициализации внутреннего [[Prototype]] свойства вновь создаваемых экземпляров - установка .prototype для общих объектов никак не влияет на разрешение свойства.

0 голосов
/ 16 ноября 2011

Во-первых, JavaScript не является языком, основанным на классах.

Это работает так же хорошо, и я не уверен, чего вы пытаетесь достичь с помощью вашего решения:

http://jsfiddle.net/jRtD2/

...