Раскрывая модуль шаблон изменен для более класса-как поведение


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

  • Экземпляры создаются из модуля (не только немедленно вернуть собственный объект)
  • Модуль может принимать аргументы и использовать их как конструктор (я не вижу во многих показательны примеры модуль)
  • Модуль может быть продлен как класса; расширение модулей наследуют его свойства/методы и может поделиться аргументов/параметров

Я, кажется, добились этого, используя только выражение функции вместо жизни, создание экземпляра родительского модуля расширения, и передача аргументов в расширении модуля на родительском экземпляре. Вот полный рабочий шаблон, который я придумал:

var Module = function({text = 'no text given'} = {}) {
    var private = {};
    private.text = text;
    private.logText = function() {
        console.log(private.text);
    };

    var public = {};
    public.logText = private.logText;

    return public;
};


var Extended = function({extraText = 'no extra text given'} = {}) {
    var parent = Module(arguments[0]);
    // Note: I chose to use an object as a parameter in this snippet, 
    // but you could also just use regular parameters and pass in
    // arguments instead of arguments[0]

    var private = {};
    private.extraText = extraText;
    private.alertText = function() {
        alert(private.extraText);
    }
  
    var public = {};
    public.logText = parent.logText;
    public.alertText = private.alertText;

    return public;
};


// TEST INSTANCES

var testModule = Module({ text: "I'm in the console." });
testModule.logText(); // "I'm in the console."

var testExt = Extended({ extraText: "I'm in an alert." });
testExt.logText(); // "no text given"
testExt.alertText(); // alerts "I'm in an alert."

var anotherExt = Extended({
  text: "I'm in the console.",
  extraText: "I'm in an alert."
});
anotherExt.logText(); // "I'm in the console."
anotherExt.alertText(); // alerts "I'm in an alert."

Сейчас он в основном ведет себя как класс, как я хотел - но мне интересно, какие ограничения/недостатки, может быть, что я не вижу. Это раскрытие модульные картины когда-нибудь использовали этот путь?



Комментарии
1 ответ

Комментарий

Это анализ кода, поэтому я укажу на некоторые проблемы стиля

Выражения функции V заявления

Есть несколько способов способов можно объявить именованную функцию.


  1. Как заявление. function functionName() { }

  2. В качестве выражения. const functionName = function() { }; обратите внимание на точку с запятой

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

Функция, объявленная как таким образом, отчетность-это наиболее безопасная форма декларации функцию и должен быть предпочтительным по сравнению с декларациями выражение.

testA(); // no error and calls testA
testB(); // throws an error ReferenceError: testB is not defined
testC(); // throws and error TypeError: testC is not a function

function testA(){};
const testB = function(){};
var testC = function(){};

const, var и let

При объявлении переменных используется соответствующий тип. const это предпочтительный тип, если вам нужно изменить значение, а затем использовать var. Если вы хотите использовать давайте в предпочтение var что до вас, но предупредил, что let не подсадили.

Избежать зарезервированные слова.

Есть набор слов, которые зарезервированы и составляют существующие или возможные в будущем жетоны. Две из них publicи private вы должны избегать использования зарезервированных слов.

Есть также много контекста слова, которые вы должны попробовать, чтобы избежать, если вы не уверены, что вы не перезаписать существующие глобальные собственность. Например parentхотя вам безопасно использовать его, я не знаю, если это просто удача или знания, которые parent это глобальный масштаб объекта АКА window.parent и вы находитесь в области, таким образом, не переписывая глобальной.

Шаблон анти

Я рассматриваю это как анти-паттерн


var Extended = function({extraText = 'no extra text given'} = {}) {
var parent = Module(arguments[0]);

Я не уверен, если вы знаете, что если вы позвоните

 Extended(); // without an argument

Тогда arguments[0] это undefinedи arguments.length === 0 но деструктурированных аргумент по имени extraText имеет значение "no extra text given"

Если вы сделали это в целях я предлагаю вам использовать альтернативный...

const Extended = function(info = {}) {         
const parent = Module(info);
info = {extraText : "no extra text given", ...info};

...как это гораздо яснее, какой умысел.

Цитаты использовать не апострофы

Чтобы избежать путаницы с строки деклараций шаблон разделенных назад цитата старайтесь не использовать апострофы (он же один совсем)

Не дублировать переменные

Объект Module создает объект private и присвоить собственность text значение аргумента text. Это просто дублирование, как только вы использовать text в функции она доступна в качестве аргумента

Дизайн

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

Простой пример объекта с государственными и частными государствами, используя геттеры и сеттеры для защиты тип (count как Number), и доступ к частному государству из частных и общественных областей (например, функция "показать")

function MyObj(text = "Nothing to see here."){

if (typeof text !== "string") { text = "Wrong type." }

// private variables
var count = 0; // Type safe from outside

// private functions declared here or in the API below
function show(){
console.log(text);
count += 1;
}

// public API also accessible from private scope
const API = {
get count() { return count },
set count(c) { // only set if a number to keep type safe state
if (!isNaN(c)) { count = Number(c) }
}
show, // public access to private function

// OR add the function here
show() {
console.log(text); // still have private access
count += 1;
}
}

// internal access
setTimeout(show, 1000); // via private function

// or via public API
setTimeout(API.show, 2000);

return API;
}

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

Рерайт

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

Следующий делает то же самое, как ваш код со значительно меньшим шумом.

function Module({text = 'no text given'} = {}) {
function logText() { console.log(text) }; // private function
return { logText };
}

function Extended(info = {}) {
info = {extraText : "no extra text given", ...info};
function alertText() { alert(info.extraText) }
return { ...Module(info), alertText };
}

1
ответ дан 8 февраля 2018 в 04:02 Источник Поделиться