2016-06-12 3 views
0

Я нахожу, что я пишу следующий JavaScript все больше и больше, и я хотел бы знать, является ли это распространенным шаблоном, и если да, то что он называется?Является ли это действительным шаблоном и что он называется?

Часть кода и шаблона:

var fruits = ["pear", "apple", "banana"]; 

var getNextFruit = function() { 
    var _index = 0, 
     _numberOfFruits = fruits.length; 

    getNextFruit = function() { 
     render(fruits[_index]); 
     _index = (_index + 1) % _numberOfFruits; 
    } 
    getNextFruit(); 
}; 

У меня есть функция, которая не принимает никаких параметров, внутри функции я переопределить функцию и немедленно вызвать его. На функциональном языке это может быть возвращаемая функция, JavaScript просто упрощает работу, потому что вы можете повторно использовать имя функции. Таким образом, вы можете расширить функциональность, не изменяя свою реализацию.

Я также могу представить, что этот шаблон очень полезен для memoization, где ваш «кеш» - это состояние, которое мы обертываем.

Я даже иногда реализую это с помощью метода get или set о функции, где я могу получить состояние, если оно имеет смысл. Примером этого является добавленная скрипка.

Потому что это в первую очередь JavaScript ориентированный вопрос: The obligatory fiddle

+0

Не уверен, что делает «render», но «производя» элементы коллекции один за другим, не заботясь о базовом типе данных, называется [iterator] (https://en.wikipedia.org/wiki/Iterator_pattern). –

+1

Образец называется «самоопределяющейся функцией», имя было введено в книге Стоянова «Шаблоны JavaScript» –

+0

Почему бы вам не определить переменную и массив «фрукты» внутри этой функции? – nnnnnn

ответ

2

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

Функция, переопределяющая себя, обычно является антипаттерном, так как это усложняет материал. Да, иногда может быть более эффективным, чтобы заменить всю функцию, чем поставить условие if (alreadyInitialised) внутри функции, но это очень редко стоит того. Когда вам нужно оптимизировать производительность, вы можете попробовать и сравнить оба подхода, но в остальном совет заключается в том, чтобы сохранить его как можно проще.

Образец «инициализируется при первом вызове» известен как laziness для чистых вычислений (в функциональном программировании) и как singleton для объектов (в ООП).

Тем не менее, в большинстве случаев нет оснований откладывать инициализацию объекта/функции/модуля независимо от того, когда он используется в первый раз. Исходные данные, взятые для него (время и память), незначительны, особенно если вы уверены, что будете нуждаться в нем в своей программе хотя бы один раз. Для этого используйте IIFE в JavaScript, который также известен как module pattern при создании объекта.

+0

Мне нужно еще немного времени, чтобы по-настоящему обмануть эту концепцию лень и как она применима к JavaScript. Я думаю, вы можете быть правы, что это означает, что это ленивая реализация. –

1

Создание функции через замыкание является довольно распространенным узором в JavaScript. Я бы лично сделать это по-другому:

var fruits = ["pear", "apple", "banana"]; 

var getNextFruit = function(fruits) { 
    var index = 0, 
     numberOfFruits = fruits.length; 

    function getNextFruit() { 
     render(fruits[_index]); 
     index = (_index + 1) % numberOfFruits; 
    } 

    return getNextFruit; 
}(fruits); 

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

function fruitGetter(fruits) { 
    var index = 0, numberOfFruits = fruits.length; 

    function getNextFruit() { 
     render(fruits[_index]); 
     index = (_index + 1) % numberOfFruits; 
    } 

    return getNextFruit; 
} 

// ... 

var getNextFruit = fruitGetter(someFruits); 

var otherFruits = fruitGetter(["kumquat", "lychee", "mango"]); 
+0

Вы абсолютно правы в подчеркивании, нет веской причины, кроме какого-то странного «стандарта кодирования», который я обычно использую , Это упрощает рефакторинг и не пропускает переменную. Чтобы вернуться к вопросу, является ли закрытие шаблоном? Или это закрытие только языка? –

+1

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

+0

И если вы хотите использовать символы подчеркивания, пожалуйста, сделайте это и почувствуйте себя хорошо. Они просто раздражают меня :) – Pointy

Смежные вопросы