Каковы преимущества классической структуры над прототипом? - PullRequest
4 голосов
/ 21 мая 2010

Я только недавно начал значительно программировать, и, будучи полностью самоучкой, к сожалению, у меня нет преимуществ подробного курса информатики. В последнее время я много читал о JavaScript и пытаюсь найти преимущество в классах по сравнению с прототипом JavaScript. Кажется, вопрос задан в середине, какой из них лучше, и я хочу увидеть его классическую сторону.

Когда я смотрю на пример прототипа:

var inst_a = {
  "X": 123,
  "Y": 321,
  add: function () {
    return this.X+this.Y;
  }
};
document.write(inst_a.add());

А потом классическая версия

function A(x,y){
  this.X = x;
  this.Y = y;
  this.add = function(){
    return this.X+this.Y;
  };
};
var inst_a = new A(123,321);
document.write(inst_a.add());

Я начал думать об этом, потому что я смотрю на новую редакцию ecmascript 5, и многим людям кажется, что они не добавляют систему классов.

Ответы [ 5 ]

3 голосов
/ 21 мая 2010

Наследование невозможно без использования псевдоклассического стиля. Посмотрите, что Дуглас Крокфорд должен сказать об этом. Даже если бы вы использовали чисто прототипную объектную структуру, вам пришлось бы создать функцию-конструктор для наследования (что делает Крокфорд, затем абстрагировать ее за методом create, затем вызвать его чисто прототипно)

3 голосов
/ 21 мая 2010

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

Так, например, вы можете добавить метод add к A.prototype только один раз, вместо того, чтобы переопределять новую копию той же функции каждый раз, когда вы создаете новый экземпляр A.

function A(x,y){
  this.X = x;
  this.Y = y;

};
//define add once, instead of every time we create a new 'A'
A.prototype.add = function(){
    return this.X+this.Y;
  };
2 голосов
/ 21 мая 2010

С помощью второго метода вы можете создавать экземпляры A, что позволяет вам иметь несколько одновременно. Например:

var inst_one = new A(123,321);
var inst_two = new A(456,654);

// some meaningful code here...
document.write(inst_one.add());


// some more meaningful code here...
document.write(inst_two.add());

Приведенный вами пример тривиален, поэтому давайте создадим более понятный пример:

function Comment(user,text){
  this.user = user;
  this.text = text;
  this.toString = function(){
    return '<span class="comment">'+this.text+' - <a class="user">'+this.user+'</a></span>';
  };
};


var comments = someFunctionThatReturnsALotOfCommentObjects();
for(c=0;c<comments.length;c++)
  document.getElementById('comments_container').innerHTML += comments[c].toString();

Это (надеюсь) демонстрирует преимущество возможности создавать несколько экземпляров класса. Это не фундаментальная концепция JavaScript, это фундаментальная объектно-ориентированное программирование концепция, поэтому, возможно, вы не знакомы с ней, если у вас не было формальных курсов по программированию.

1 голос
/ 21 мая 2010

Чтобы быть справедливым, JavaScript имеет классы.Ну, может кто-то поспорит с этим, но я считаю, что это просто семантическое разделение волос.Если для создания объектов выбран класс, то функция JavaScript может служить в этом качестве.Здесь нет большой разницы в функциях, только форма:

class someObj
{
    private int x;
    public int returnX()
    {
        return x;
    }
}
someObj temp = new someObj();

-

function someObj {
    var x;
    this.returnX = function() {
        return x;
    };
}
var temp = new someObj();

Под капотом они разные, но вы можете использовать любую формучтобы служить той же цели.

Прототип действительно отличается по наследству.В прототипическом наследовании, когда вы создаете новый объект, вы действительно копируете экземпляр объекта-прототипа, а затем добавляете в него новые поля или элементы.Классическое наследование, с другой стороны, имеет дело не с экземпляром, а с «черным шрифтом».Например, в JavaScript вы сказали бы:

temp.prototype = new someOtherObj(); //Creating a new instance to serve as the prototype.

В классическом языке вы можете сказать:

class someObj : someOtherObj //Copying the "blue print" over.

Смысл в том, что данные будут совместно использоваться производными объектами в прототипеязык.Однажды я написал функцию, и у меня была другая функция, созданная на основе прототипирования в JavaScript.Этот базовый объект содержал ссылку на объект DOM, и когда я изменял его в одном дочернем объекте, он менял его для всех экземпляров этого дочернего объекта.Это потому, что, опять же, на языке прототипов вы производите от экземпляра, а не от «черновика».

0 голосов
/ 21 мая 2010

Классическая версия позволяет объявлять закрытые переменные в области "внутри" объекта, тогда как версия прототипа - нет.

...