Правильный дизайн класса - PullRequest
5 голосов
/ 28 января 2011

У меня есть несколько вопросов о JavaScript, которые мне нужно закрепить. Чтобы помочь, у меня есть простое определение класса, которое я пишу:

var dataSource = function (src, extension) {
    return {
        exists: function () {
            // function to check if the source exists (src *should* be an object
            // and extension should be a string in the format ".property.property.theSource".
            // this function will return true if src.property.property.theSource exists)
        },
        get: function () {
            // function will return the source (ex: return src.property.property.theSource)
        }
    }   
}();

Вопросы:

1) В моем текущем понимании JavaScript вызов dataSource () создаст новый объект с его собственными копиями методов exist () и get (). Я прав?

2) Есть ли способ написать это так, чтобы, если я создаю 1 000 000 объектов источника данных, у меня была только одна копия каждой функции?

3) Должен ли я вообще интересоваться (2)?

Ответы [ 5 ]

7 голосов
/ 28 января 2011

У вас есть функция, которая возвращает значение объекта, а не класс JS.

Вы захотите проверить, используя DataSource.prototype, и вы должны добавить свойства или изменить this в вашем конструкторе, если вы хотите использовать это вместе с new

Вы, вероятно, должны делать что-то вроде этого:

function DataSource(src, extension){
    //Make sure this behaves correctly if someone forgets to use new
    if (! this instanceof DataSource)
         return new DataSource(src,extension);
    //store the constructor arguments
    //so you can use them in the shared methods below
    this._src=src;
    this._extension=extension;
}
DataSource.prototype.exists=function(){
    //use this._src and this._extension here
    //This method will be available to all
    //objects constructed by new DataSource(...)
};
DataSource.prototype.get=function(){
    //use this._src and this._extension here
    //This method will be available to all
    //objects constructed by new DataSource(...)
};

var instance = new DataSource('a source','an extension');

Редактировать: Вы упоминали, что предпочли бы «частные» переменные

Построение замыканий - это единственный переносимый способ имитации частных свойств, однако, по моему опыту, перед ними ставим префикс _ и в вашей организации существует соглашение не полагаться на префиксные переменные _ в большинстве ситуаций

5 голосов
/ 28 января 2011

Прототип - это то, что вы хотите использовать. Он будет сохранен один раз и связан со всеми экземплярами объекта.

0 голосов
/ 08 ноября 2017

Обновлено для синтаксиса класса ES6 (это еще один способ написания ответа @ tobyodavies):

class DataSource {
    constructor(src, extension) {
        this._src = src; 
        this._extension = extension; 
    }
    exists() {

    }
    get() {

    }
};
var instance = new DataSource('a source','an extension');

Нет необходимости проверять, вызывался ли класс с экземпляром new, так какневозможно с классами ES6.Он вернется с ошибкой Class constructor DataSource cannot be invoked without 'new'.

0 голосов
/ 28 января 2011

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

Согласно вашему требованию, если вы отделите переменные класса от возвращаемых типов и объявите только один раз (для всех), тогда для каждого экземпляра эти свойства будут доступны,Это означает, что эти переменные (определенные как ExampleClass.prototype = function () {}) будут работать как статические переменные в c / c ++

0 голосов
/ 28 января 2011

Вы можете создать этот класс, чтобы легко создавать несколько копий.

  • Редактировать - Добавлены аргументы конструктора.

    function DataSource(src, extension) {
        this.src = src,
        this.extension = extension,
        this.exists = function() {
            // function to check if the source exists (src *should* be an object
            // and extension should be a string in the format ".property.property.theSource".
            // this function will return true if src.property.property.theSource exists)
        },
        this.get = function() {
            // function will return the source (ex: return src.property.property.theSource)
        }
    }
    dataSource1 = new DataSource();
    dataSource2 = new DataSource();
    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...