Объектно-ориентированный JavaScript с прототипами против замыканий

Мне любопытно, в чем разница между следующими методами ООП javascript. Кажется, что они в конечном итоге делают то же самое, но считается ли один лучше другого?

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

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

var myBook = new Book('War and Peace');
alert(myBook.getTitle())

против

function Book(title) {
    var book = {
        title: title
    };
    book.getTitle = function () {
        return this.title;
    };
    return book;
}

var myBook = Book('War and Peace');
alert(myBook.getTitle())
62
задан Marcel Korpel 25 August 2010 в 09:00
поделиться

3 ответа

Второй на самом деле не создает экземпляр, он просто возвращает объект. Это означает, что вы не можете использовать такие операторы, как instanceof. Например.в первом случае вы можете сделать if (myBook instanceof Book), чтобы проверить, является ли переменная типом книги, а во втором примере это не удастся.

Если вы хотите указать свои методы объекта в конструкторе, это правильный способ сделать это:

function Book(title) {
    this.title = title;

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

var myBook = new Book('War and Peace');
alert(myBook.getTitle())

Хотя в этом примере оба ведут себя одинаково, есть различия. С реализацией на основе замыкания вы можете иметь закрытые переменные и методы (просто не раскрывайте их в объекте this). Таким образом, вы можете сделать что-то вроде:

function Book(title) {
    var title_;

    this.getTitle = function() {
        return title_;
    };

    this.setTitle = function(title) {
        title_ = title;
    };

    // should use the setter in case it does something else than just assign
    this.setTitle(title);
}

Код вне функции Book не может получить прямой доступ к переменной-члену, они должны использовать методы доступа.

Еще одно большое отличие — производительность; Классификация на основе прототипа обычно намного быстрее из-за некоторых накладных расходов, связанных с использованием замыканий. Вы можете прочитать о различиях в производительности в этой статье: http://blogs.msdn.com/b/kristoffer/archive/2007/02/13/javascript-prototype-versus-closure-execution-speed.aspx

46
ответ дан 24 November 2019 в 16:53
поделиться

Первый метод предназначен для использования JavaScript. Последняя является более современной техникой, частично популяризированной Дугласом Крокфордом. Эта техника гораздо более гибкая.

Вы также можете сделать следующее:

function Book(title) {
    return {
        getTitle: function () {
            return title;
        }
    }
}

Возвращаемый объект будет просто иметь метод доступа с именем getTitle, который вернет аргумент, содержащийся в закрытии.

У Крокфорда есть хорошая страница Private Members in JavaScript — определенно стоит прочитать, чтобы увидеть различные варианты.

11
ответ дан 24 November 2019 в 16:53
поделиться

вот статья об этом в целом Book наследуется от Book.prototype. В первом примере вы добавляете функцию в getTitle Book.prototype

0
ответ дан 24 November 2019 в 16:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: